中断

我翻译的很菜,我知道!

有很多句子不通顺,因为没有在网上找到中文的,自己看又看不懂,所以凑活着翻译了一下。我知道也有很多像我一样菜的,看英文离不开翻译工具。

大家尽管骂吧!!!

菜,也得有胆量留名:hnwyllmm

谁有更好的,或者修改了的,麻烦发给我:hnwyllmm@126.com

What are Interrupts?

什么是中端?

When receiving data and change in status from I/O Ports, we have two methods available to us. We can Poll(调查) the port, which involves(涉及) reading the status of the port at fixed intervals(区间,间隔) to determine whether any data has been received or a change of status has occurred. If so, then we can branch(分支) to a routine to service the ports requests.

我们有两种方法接收数据和改变I/O端口的状态。我们可以查询(Poll)端口,定时读取端口状态以确定是否有数据到来或者状态改变。如果是这样的话,我们可以进入相应端口要求的分支。

As you could imagine, polling the port would consume(耗费) quite some time. Time which could be used doing other things such refreshing the screen, displaying the time etc. A better alternative would be to use Interrupts. Here, the processor does your tasks such as refreshing the screen, displaying the time etc, and when a I/O Port/Device needs attention as a byte has been received or status has changed, then it sends a Interrupt Request (IRQ) to the processor.

你可以想象的到,查询端口将会消耗相当大的时间。这些时间可以用来做其它的事情,例如刷新屏幕,显示时间等等。一个更好的选择是使用中断。这样,处理器可以做些像刷新屏幕,显示时间等的工作,并且当I/O端口或设备收到一个字节或者状态改变时,它就会发送一个中断请求(IRQ)给处理器。

Once the processor receives an Interrupt Request, it finishes its current instruction, places a few things on the stack, and executes the appropriate Interrupt Service Routine (ISR) which can remove the byte from the port and place it in a buffer. Once the ISR has finished, the processor returns to where it left off(离开).

一旦处理器接收到一个中断请求,它就会终止当前的指令,在栈上放置一些东西,运行合适的可以将端口的字节放到缓冲区的中断服务程序(ISR)。一旦ISR结束,处理器就会返回到它中断的地方。

Using this method, the processor doesn't have to waste time, looking to see if your I/O Device is in need of attention, but rather the device will interrupt the processor when it needs attention.

使用这个方法,处理器就不用浪费时间去看I/O设备是否需要注意,而是设备需要注意时就会中断处理器。

Interrupts and Intel Architecture

Interrupts do not have to be entirely associated with I/O devices. The 8086 family of microprocessors provides 256 interrupts, many of these are only for use as software interrupts, which we do not attempt to explain in this document.

中断并不需要完全和I/O设备关联起来。8086系列的微处理器提供了256个中断,其中大部分仅仅用作软中断,而我们不打算解释它。

The 8086 series of microprocessors has an Interrupt Vector Table situated at 0000:0000 which extends for 1024 bytes. The Interrupt Vector table holds the address of the Interrupt Service Routines(ISR), all four bytes in length. This gives us room for the 256 Interrupt Vectors.

8086系列的微处理器有一个定位在0000:0000,扩展到1024字节的中断向量表。中断向量表包含了中断服务程序(ISR),每个都是四字节长。这给我们提供了256个中断向量地址。

INT (Hex) IRQ Common Uses

序号(十六进制) IRQ(中断请求) 一般用途

00 - 01 Exception Handlers

00 – 01 异常处理

02 Non-Maskable IRQ Non-Maskable IRQ (Parity Errors)

02 不可屏蔽IRQ 不可屏蔽IRQ(奇偶错误)

03 - 07 Exception Handlers

03 – 07 异常处理

08 Hardware IRQ0 System Timer

08 硬件IRQ0 系统时钟

09 Hardware IRQ1 Keyboard

09 硬件IRQ1 键盘

0A Hardware IRQ2 Redirected

0A 硬件 IRQ2 重定向

0B Hardware IRQ3 Serial Comms. COM2/COM4

0B 硬件 IRQ3 串口 COM2/COM4

0C Hardware IRQ4 Serial Comms. COM1/COM3

0C 硬件IRQ4 串口 COM1/COM3

0D Hardware IRQ5 Reserved/Sound Card

0D 硬件 IRQ5 保留/声卡

0E Hardware IRQ6 Floppy Disk Controller

0E 硬件 IRQ6 软盘控制器

0F Hardware IRQ7 Parallel Comms.

0F 硬件 IRQ7 并口

10 - 6F Software Interrupts

10 – 6F 软件中断

70 Hardware IRQ8 Real Time Clock

70 硬件IRQ8 实时时钟

71 Hardware IRQ9 Redirected IRQ2

71 硬件 IRQ9 重定向IRQ2

72 Hardware IRQ10 Reserved

72 硬件 IRQ10 保留

73 Hardware IRQ11 Reserved

73 硬件IRQ11 保留

74 Hardware IRQ12 PS/2 Mouse

74 硬件 IRQ12 PS/2鼠标

75 Hardware IRQ13 Math's Co-Processor

75 硬件IRQ13 数学协处理器

76 Hardware IRQ14 Hard Disk Drive

76 硬件 IRQ14 硬盘驱动器

77 Hardware IRQ15 Reserved

77 硬件 IRQ15 保留

78 - FF Software Interrupts

78 – FF 软件中断

Table 1 : x86 Interrupt Vectors

1x86 中断向量

 

The average PC, only has 15 Hardware IRQ's plus one Non-Maskable(可屏蔽的) IRQ. The rest of the interrupt vectors are used for software interrupts and exception handlers. Exception handlers are routines like ISR's which get called or interrupted when an error results. Such an example is the first Interrupt Vector which holds the address of the Divide By Zero, Exception handler. When a divide by zero occurs the Microprocessor fetches the address at 0000:0000 and starts executing the code at this Address.

一般的PC机,仅有15个硬件中断请求和一个不可屏蔽中断。剩余的中断向量用于软件中断和异常处理。当一个错误产生时像ISR的异常处理程序会被调用或中断。这样的一个例子是包含被零除的异常处理的第一个中断向量。当被零除的情况发生时微处理器找到在0000:0000的地址并运行这个地址的代码。

Hardware Interrupts

硬件中断

The Programmable Interrupt Controller (PIC) handles hardware interrupts. Most PC's will have two of them located at different addresses. One handles IRQ's 0 to 7 and the other, IRQ's 8 to 15, giving a total of 15 individual IRQ lines, as the second PIC is cascaded(级联的) into the first, using IRQ2.

可编程中断控制器(PIC)处理硬件中断。大多数PC有两个位于不同地址的PIC。一个处理IRQ0~7,另一个处理IRQ8~15,一共有15个不同的IRQ线,第二个级练到第一个的IRQ2上。

Most of the PIC's initialization is done by BIOS, thus we only have to worry about two instructions. The PIC has a facility(功能) available where we can mask individual IRQ's so that these requests will not reach the Processor. Thus the first instruction is to the Operation Control Word (OCW1) to set which IRQ's to mask and which IRQ's not too.

BIOS做了大部分的PIC初始化工作,因此我们仅仅需要担心两个指令。PIC提供了单独屏蔽某个IRQ的功能,以便那个请求不会到达处理器。这样第一条指令就是操作控制字(OCW1)设置或屏蔽IRQ

As there are two PIC's located at different addresses, we must first determine which PIC we need to use. The first PIC, located at Base Address 0x20h controls IRQ 0 to IRQ 7. The bit format of PIC1's Operation Control Word 1 is shown on the next page in table 2.

因为有两个位于不同地址的饿PIC,我们一定首先确定我们使用那个PIC。第一个PIC,位于基址0x20h,控制IRQ0IRQ7。下页的表2展示了PIC1的操作控制字1的位格式。

Bit Disable IRQ Function

位禁用IRQ功能

7 IRQ7 Parallel Port

7 IRQ7 并行端口

6 IRQ6 Floppy Disk Controller

6 IRQ6 软盘控制器

5 IRQ5 Reserved/Sound Card

5 IRQ5 保留/声卡

4 IRQ4 Serial Port

4 IRQ4 串口

3 IRQ3 Serial Port

3 IRQ3 串口

2 IRQ2 PIC2

2 IRQ2 PIC2

1 IRQ1 Keyboard

1 IRQ1 键盘

0 IRQ0 System Timer

0 IRQ0 系统时钟

Table 2 : PIC1 Operation Control Word 1 (0x21)

2PIC1 操作控制字10x21

Note that IRQ 2 is connected to PIC2, thus if you mask this IRQ, then you will be disabling IRQ's 8 to 15.

注意:IRQ2连接PIC2,因此如果你屏蔽这个IRQ,就会禁用IRQ8~15

The second PIC located at a base address of 0xA0h controls IRQs 8 to 15. Below is the

individual bits required to make up it's Operation Control Word.

第二个PIC基址位于0xA0h,控制IRQ8~15。下面是标记操作控制字的需要的单独的位。

Bit Disable IRQ Function

位禁用功能

7 IRQ15 Reserved

7 IRQ15 保留

6 IRQ14 Hard Disk Drive

6 IRQ14 硬盘驱动器

5 IRQ13 Maths Co-Processor

5 IRQ13 数学协处理器

4 IRQ12 PS/2 Mouse

4 IRQ12 PS/2鼠标

3 IRQ11 Reserved

3 IRQ11 保留

2 IRQ10 Reserved

2 IRQ10 保留

1 IRQ9 Redirected IRQ2

1 IRQ9 重定向IRQ2

0 IRQ8 Real Time Clock

0 IRQ8 实时时钟

Table 3 : PIC2 Operation Control Word 1 (0xA1)

3PIC2 操作控制字(0xA1

 

As the above table shows the bits required to disable an IRQ, we must invert them should we want to enable an IRQ. For example, if we want to enable IRQ 3 then we would send the byte 0xF7 as OCW1 to PIC1. But what happens if one of these IRQs are already enabled and then we come along and disable it?

上面的表显示了要禁用一个IRQ的位,我们想要启用一个IRQ必须翻转那个位。例如,如果想要启用IRQ3,我们就要发送字节0xF7作为OCW1PIC1。但是如果在这些IRQ已经启用的同时我们禁用它会发生什么呢?

Therefore we must first get the mask and use the AND function to output the byte back to the register with our changes so to cause the least upset(扰乱) to the other IRQs. Going back to our IRQ3 example, we could use outportb(0x21,(inportb(0x21) & 0xF7); to enable IRQ3. Take note that the OCW1 goes to the register at Base + 1.

这样我们必须先获取屏蔽位,然后与结果相与输出到寄存器,以因此其它IRQ最少的改变。返回到我们的IRQ3例子,我们可以用outportb(0x21,(inportb(0x21) & 0xF7);启用IRQ3。注意OCW1位于基址+1

The same procedure must be used to mask (disable) an IRQ once we are finished with it.

我们屏蔽(禁用)一个IRQ时必须使用相同的过程。

However this time we must OR the byte 0x08 to the contents of OCW1. Such and example of code is outportb(0x21,(inportb(0x21) | 0x08);

然而这次我们必须用OCW1的内容与字节0x08相或。示例代码:outportb(0x21, (inportb(0x21) | 0x08);

The other PIC instruction we have to worry about is the End of Interrupt (EOI). This is sent to the PIC at the end of the Interrupt Service Routine so that the PIC can reset the In Service Register.

我们需要考虑的另一个PIC指令时中断结束(EOI)。在中断服务程序结束时会发送,以便PIC可以重置中断服务寄存器。

See The Programmable Interrupt Controller (Page 7) for more information. An EOI can be sent using outportb(0x20,0x20); for PIC1 or outportb(0xA0,0x20); for PIC2

获取更多信息,请看可编程中断控制器(第7页)。对于PIC1可以使用outportb(0x20, 0x20);发送一个EOI,对于PIC2使用outportb(0xA0,0x20);

Implementing the Interrupt Service Routine (ISR)

实现中断服务程序(ISR

In C you can implement your ISR using void interrupt yourisr() where yourisr is a far pointer, pointing to the address that your Interrupt Service Routine will reside in memory. This is later placed in the Interrupt Vector Table so that, it will be called when interrupted.

C中,你可以使用void interrupt yourisr()实现你的ISRyourisr是一个指向驻留在内存中的中断服务程序的地址。它将会被放在中断向量列表中,以便中断时被调用。

void interrupt yourisr() /* Interrupt Service Routine (ISR) */

{

disable();

/* Body of ISR goes here */

oldhandler();

outportb(0x20,0x20); /* Send EOI to PIC1 */

enable();

}

void interrupt yourisr() /* 中断服务程序 (ISR) */

{

disable();

/* ISR代码 */

oldhandler();

outportb(0x20,0x20); /* PIC1发送EOI */

enable();

}

 

void interrupt yourisr() defines this function as an Interrupt Service Routine. disable(); clears the interrupt flag, so that no other hardware interrupts ,except a NMI (Non-Maskable Interrupt) can occur. Otherwise, and interrupt with a higher priority that this one can interrupt the execution of this ISR. However this is not really a problem in many cases, thus is optional.

void interrupt yourisr() 表明了这个函数是一个中断服务程序。disable(); 清除中断标志,以便不会有其它的硬中断,除了NMI(不可屏蔽中断)可以出现。否则,一个比这个优先级高的中断会执行这个中断服务程序。然而在大多数情况下这并不是一个问题,这是可选的。

The body of your ISR will include code which you want to execute upon this interrupt request being activated. Most Ports/UARTs may interrupt the processor for a range of reasons, eg byte received, time-outs, FIFO buffer empty, overruns etc, thus the nature of the interrupt has to be determined. This is normally achieved by reading the status registers of the port you are using. Once it has been established, you can service it's requests.

ISR的内容包括你想要中断要求激活后执行的代码。大部分端口/UART可能会因为一系列的原因中断处理器,例如接收到字节数据、超时、FIFO缓冲区空、超载运行等等,这样终端的性质就被定下来了。通常通过读取你正在使用的端口状态寄存器来获取。一旦那被建立起来,你就可以满足它的要求。

If you read any data from a port, it is normally common practice to place it in a buffer, rather that immediately writing it to the screen, inhibiting(抑制) further interrupts to be processed. Most Ports these days will have FIFO buffers which can contain more than one byte, thus repeat your read routine, until the FIFO is empty, then exit your ISR.

如果你从端口读到了一些数据,通常将它们放到缓冲区上更实际些,而不是立即写到屏幕上,以抑制更深层的需要处理的中断。现在大部分端口都有可以容纳超过一个字节的FIFO缓冲区,这样重复你的读程序直到FIFO为空才退出你的ISR

In some cases it may be appropriate to chain the old ISR to this one. Such an example would be the Clock Interrupt. Other TSR(终止并驻留)or resident(驻存的) programs may also be using it, thus if you intercept(拦截) the interrupt and keep it all for yourself, the other ISR's can no longer function possibly causing some side effects. However for Serial/Parallel Ports this is not a problem. To chain the old ISR to your new ISR, you can call it using oldhandler(); where oldhandler points to your old ISR.

有些情况下将旧的ISR和现在的连起来比较合适。这样的一个例子就是时钟中断。其它的TSR或者驻存的程序可能正在使用它,这样如果你拦截中断并全部保留你自己的,其它的ISR就可能引起副作用而不能工作。然而对于串口/并口来说并不是一个问题。你可以调用oldhandler();来将旧的ISR和你的新的ISR连接起来,oldhandler指向你的旧的ISR

Before we can return from the interrupt, we must tell the Programmable Interrupt Controller, that we are ending the interrupt by sending an EOI (End of Interrupt 0x10) to it. As there are two PIC's you must first establish which one to send it to. Use outportb(0x20,0x20); for PIC 1 (IRQ 0 - 7) or outportb(0xA0,0x20); for PIC 2 (IRQ 8 - 15).

在我们从中断返回前,我们一定要通过发送一个EOI(中断结束0x10)来告诉可编程中断控制器。由于这有两个PIC,你必须首先确立发送到哪一个。对于PIC1IRQ0 – 7)使用outportb(0x20,0x20);PIC2IRQ 8 – 15)使用outportb(0xA0,0x20);

Note: If using PIC2, then an EOI has to be sent to both PIC1 and PIC2.

注意:如果使用PIC2,必须给PIC1PIC2都发送EOI

Using your new Interrupt Service Routine

使用新的中断服务程序

Now that we have written our new interrupt service routine, we can start looking at how to implement it. The following code segment shows the basic usage of your new ISR. For this example we have chosen to use IRQ 3.

现在我们已经写了我们新的中断服务程序,我们可以看看怎么执行它。下面的代码段展示了你的新的ISR的基本用处。这个例子中我们选择了使用IRQ3

 

#include <dos.h>

#define INTNO 0x0B /* Interrupt Number - See Table 1 */

void main(void)

{

oldhandler = getvect(INTNO); /* Save Old Interrupt Vector */

setvect(INTNO, yourisr); /* Set New Interrupt Vector Entry */

outportb(0x21,(inportb(0x21) & 0xF7)); /* Un-Mask (Enable) IRQ3 */

/* Set Card - Port to Generate Interrupts */

/* Body of Program Goes Here */

/* Reset Card - Port as to Stop Generating Interrupts */

outportb(0x21,(inportb(0x21) | 0x08)); /* Mask (Disable) IRQ3 */

setvect(INTNO, oldhandler); /* Restore old Interrupt Vector Before

Exit */

}

 

#include <dos.h>

#define INTNO 0x0B /* 中断数字 查看表1 */

void main(void)

{

oldhandler = getvect(INTNO); /* 保存旧的中断向量 */

setvect(INTNO, yourisr); /* 设置新的中断向量条目 */

outportb(0x21,(inportb(0x21) & 0xF7)); /* 取消屏蔽(启用)IRQ3 */

/* 设置卡 端口来产生中断 */

/* 程序代码到这 */

/* 重置卡 端口来停止产生中断 */

outportb(0x21,(inportb(0x21) | 0x08)); /* 屏蔽(禁用)IRQ3 */

setvect(INTNO, oldhandler); /* 退出前还原旧的中断向量 */

}

 

Before you can place the address of your new ISR in the interrupt vector table, you must first save the old interrupt vector, so that you can restore it once you exit your program. This is done using oldhandler = getvect(INTNO); where INTNO is the number of the interrupt vector you wish to return. Before oldhandler can be used, you must first declare it using void interrupt (*oldhandler)();

在你将你的新的ISR放到中断向量表前,一定要先保存旧的中断向量,以便一旦退出你的程序是还原它。可以使用oldhandler = getvect(INTNO);来做,INTNO是你希望返回的中断向量的数字。在使用oldhandler前,你一定要先试用void interrupt (*oldhandler)();声明它。

Once the old interrupt vector is stored, we can now install your new ISR into the interrupt vector table. This is done using the line setvect(INTNO, yourisr); where yourisr points to your interrupt service routine.

一旦保存你的旧的中断向量,我们现在可以安装你的新的ISR到中断向量表中。可以使用setvect(INTNO, yourisr);这一行来做,yourisr指向你的中断服务程序。

The IRQ which you are using must now be unmasked. We have already discussed this earlier.

你正在使用的IRQ现在一定是非屏蔽的。我们之前已经讨论过了。

See Hardware Interrupts (Page 3.)

请看硬件中断(第3页)

Most Ports/UARTs will need some initialization to be able to generate interrupts. For Example, The Standard Parallel(并行的) Port (SPP) will require Bit 4 of the Control Port, Enable IRQ Via ACK Line to be set at Base + 2. The Serial Port will require the appropriate setting of Bits 0 to 4 of the Interrupt Enable Register (IER) located at Base + 1.

大部分端口/UART需要一些初始化才能产生中断。例如,标准并行端口(SPP)要求控制端口的位4通过设置ACK线在基址+2上启用IRQ。串口要求适当的设置位于基址+1的中断使能寄存器(IER)的位0到位4

Your body of the program normally consists of a few housekeeping(家政开支) tasks depending upon your application. Here you look for new keys pressed, menus being selected, updating clocks, checking for incoming data in buffers etc, knowing that any data from your Ports will be automatically read and processed, by the ISR.

你的程序体根据你的应用程序通常包含一些家政开支任务。在这,你查找新的被按下的键、被选中的菜单、更新的时钟、监测缓冲区中到来的数据等等,知道从你的端口来的数据将会被ISR自动读取和处理。

If you like implementing ISR's so much, you can attach your own ISR to the Keyboard Interrupt, so any keys being pressed will be automatically handled by another ISR, and even one to the clock. Upon every 18.2 ticks you can update the seconds on your display! The possibilities of ISR's are endless.

如果你很喜欢实现ISR,可以将你自己的ISR与键盘中断连接起来,这样任何按键被按下就会被另一个ISR自动处理,甚至做一个可以和时钟关联起来的。每18.2个滴答你就可以更新一下你显示的秒数。ISR的可能性是无穷尽的。

Before you exit your program always restore the old interrupt vector, so that your computer doesn't become unstable. This is done using setvect(INTNO, oldhandler); , where oldhandler points to the old interrupt service routine, which we stored using oldhandler = getvect(INTNO);

在退出你的程序前常常要恢复旧的中断向量,因此你的计算机变的不稳定。可以用setvect(INTNO, oldhandler);来实现,oldhandler指向旧的中断服务程序,通过oldhandler = getvect(INTNO);来保存。

The Programmable Interrupt Controller

可编程中断控制器

As we have all ready discussed, the Interrupt ReQuests (IRQ's) of a PC is handled by two 8259 Programmable Interrupt Controllers. On the old XT's/AT's these were two 28 Pin DIP IC's, but as you can imagine, things have changed dramatically since then. While the operational principal is still the same, the PIC is now integrated somewhere into your chipset, along with many other devices.

就像我们已经讨论过的,一个微机的中断请求(IRQ)需要两个8259可编程中断控制器处理。在老的XT/AT机上有两个28DIP封装集成电路(IC),你可以想象得到,从那时事情发生了很大的变化。然而运作的主体仍然相同,PIC现在和很多其它的设备集成到了你的芯片上。

 

The basic block diagram of the PIC is shown above. The 8 individual interrupt request lines are first passed through the Interrupt Mask Register (IMR) to see if they have been masked or not. If they are masked, then the request isn't processed any further. However if they are not masked, they will register their request with the Interrupt Request Register (IRR).

PIC的基本框图如上所示。8单独的中断请求线首先通过中断屏蔽寄存器(IMR)查看它们是否已被屏蔽。如果它们被屏蔽,请求不会做任何进一步的处理。然而如果它们没有被屏蔽,它们将注册中断请求寄存器(IRR)的请求。

The Interrupt Request Register will hold all the requested IRQ's until they have been dealt with appropriately. If required, this register can be read by setting certain bits of the Operation Control Word 3. The Priority Resolver simply selects the IRQ of highest priority. The higher priority interrupts are the lower numbered ones. For Example IRQ 0 has the highest priority followed by IRQ1 etc.

中断请求寄存器将会保留所有的已请求IRQ,直到它们被合适的处理。如果请求过了,可以通过设置操作控制字3的某些位来读取这些寄存器。优先级解析器只管选择优先级最高的IRQ。高优先级的中断是编号较低的那些。例如IRQ 0具有最高优先级,IRQ 1紧随其后。

Now that the PIC has determined which IRQ to process, it is now time to tell the processor, so that it can call your ISR for you. This process is done by sending a INT to the processor, i.e. the INT line on the processor is asserted. The processor will then finish the current instruction it's processing and acknowledge your INT request with a INTA (Interrupt Acknowledge) pulse.

现在,PIC据顶处理哪个IRQ,现在是时候告诉处理器以便它调用你的ISR。这个过程是通过给处理器发送一个INT,即处理器上的INT线断言。处理器将会结束当前处理的指令,用一个INTA(中断应答)脉冲响应你的INT请求。

Upon receiving the processor's INTA, the IRQ which the PIC is processing at the time is stored in the In Service Register (ISR) which as the name suggests, shows which IRQ is currently in service. The IRQ's bit is also reset in the Interrupt Request Register, as it is no longer requesting service but actually getting service.

在收到处理器的INTA时,PIC当时正在处理的IRQ存储在中断服务寄存器(In Service Register)中(ISR),就像它的名字标明的那样,ISR显示当前哪个IRQ正在服务中。中断请求寄存器中的IRQ位也要复位,因为它不再请求服务而实际上接受服务。

Another INTA pulse will be sent by the processor, to tell the PIC to place a 8 bit pointer on the data bus, corresponding(相应的) to the IRQ number. If an IRQ serviced by PIC2 is requesting the service, then PIC2 will send the pointer to the processor. The Master (PIC1) at this stage, will select PIC2 to send the pointer, by placing PIC2's Slave ID on the Cascade(级联) lines, which is a 3 wire bus between all the PIC's in a system.

处理器将会发送另一个INTA脉冲,老告诉PIC在数据总线上放置一个对应IRQ数字的8位指针。如果一个由PIC2服务的IRQ正在请求服务,PIC2将会发送指针给处理器。主PICPIC1)在这个阶段,将会通过在一个系统中所有PIC之间的3线总线的级联线上放置PIC2的附属ID来选择PIC2来发送那个指针。

The 5 most significant bits of this pointer is set using the Initialization Command Word 2 (ICW2). This will be 00001 for PIC1 and 01110 for PIC2. The three least significant bits, will be sent due to which IRQ is being serviced. For example, if IRQ3 is requesting service then the 8 bit pointer will be made up with 00001 for the 5 most significant bits and 011 (IR3) for the least significant bits.

使用初始化命令字2ICW2)设置这个指针的5个最高有效位。00001对应PIC1,01110对应PIC23个最低有效位的发送要根据哪个IRQ正在接受服务。例如,如果IRQ3正在请求服务,8位的指针将会由为00001的高5位和为011IRQ3)的最低有效位组成。

Put this together and you get 00001011 or 0x0B which just happens to be IRQ3's interrupt vector.

把这放到一块,你会得到000010110x0B,这正好是IRQ3的中断向量。

For PIC2, the same principal is applied. If IRQ10 is requesting service, then 01110010 will be sent, which just happens to represent Interrupt 72h. IRQ10 happens to be connected to IR2 on the Second PIC, thus 010 is used as the least significant bits.

对于PIC2,应用相同的规则。如果IRQ10正在请求服务,就会发送01110010,正好代表中断72hIRQ10正好连接到第二个PICIR2上,因此010就作为最低有效位。

Once your ISR has done everything it needs, it sends an End of Interrupt (EOI) to the PIC, which resets the In-Service Register. If the request came from PIC2, then EOI's are required to be sent to both PICs. The PIC will then determine the next highest priority interrupt and repeat the same process. If no Interrupt Requests are present, then the PIC waits for the next request before interrupting the processor.

一旦你的ISR做完了它需要的所有工作,它会发送一个中断结束标识(EOI)给PIC,这将重置中断服务寄存器。如果那个请求来自PIC2,那么就要求给两个PIC都发送EOIPIC将会确定下一个最高优先级的中断然后重复同样的过程。如果当前没有中断请求,那么PIC会在中断处理器前等待下一个请求。

IRQ2/IRQ9 Redirection

IRQ2/IRQ9重定向

The redirection of IRQ2 causes quite some confusion, and thus is discussed here. In the original XT's there were only one PIC, thus only eight IRQ's. However users soon out grew these resources, thus an additional 7 IRQ's were added to the PC. This involved attaching another PIC to the existing one already in the XT. Compatibility always causes problems as the new configuration still had to be compatible with old hardware and software. The "new" configuration is shown below.

IRQ2的重定向确实会引起很多疑惑,因此在此讨论一下。在原始的XT中仅有一个PIC,也就是仅8IRQ。然而用户很快就用光了这些资源,因此一个额外的7 IRQ添加到了PC上。这就涉及到了在已经存在的XT上附加一个PIC兼容性总是导致新的配置问题:仍是兼容旧的硬件和软件。“新的”配置图如下:

 

The CPU only has one interrupt line, thus the second controller had to be connected to the first controller, in a master/slave configuration. IRQ2 was selected for this. By using IRQ2 for the second controller, no other devices could use IRQ2, so what happened to all these devices using IRQ2?

CPU仅有一个中断线,这样第二个控制器就必须以主从配置连接到第一个控制器上。选择了IRQ2做这个。使用IRQ2连接第二个控制器,不能再有其它的设备使用IRQ2,这样的话使用IRQ2的设备会发生什么呢?

Nothing, the interrupt request line found on the bus, was simply diverted into the IRQ 9 input. As no devices yet used the second PIC or IRQ9, this could be done.

什么都没有,在总线上发现中断请求时被简单的改到IRQ9上。由于没有设备使用第二个PICIRQ9,因此可以这样做。

The next problem was that a hardware device using IRQ2 would install it's ISR at INT 0x0A.

下一个问题是一个使用IRQ2的硬件设备将在INT 0x0A上安装它的ISR

Therefore an ISR routine was used at INT 71h, which sent a EOI to PIC2 and then called the ISR at INT 0x0A. If you dis-assemble the ISR for IRQ9, it will go a little like,

因此,一个在INT 71h使用的ISR程序,向PIC2发送一个EOI然后调用在INT 0x0AISR。如果你反汇编IRQ9ISR,它会有点像:

MOV AL,20

OUT A0,AL ; Send EOI to PIC2

INT 0A ; Call ISR for IRQ2

IRET

 

MOV AL,20

OUT A0,AL ; PIC2发送EOI

INT 0A ; IRQ2调用ISR

IRET

 

The routine only has to send a EOI to PIC2, as it is expected that a ISR routine written for IRQ2 will send a EOI to PIC1. This example destroys the contents of Register AL, thus this must be placed on the stack first (Not shown in example). As PIC2 is initialized with a Slave on IRQ2, any request using PIC2 will not call the ISR routine for IRQ2. The 8 bit pointer will come from PIC2.

该程序仅向PIC2发送一个EOI,因为它预期IRQ2ISR程序将会向PCI1发送一个EOI。这个示例破坏了寄存器AL的内容,这样,这必须先放置在栈上(例子中没有展示)。因为PCI2初始化成了IRQ2的从属,任何使用PIC2的请求不会调用IRQ2ISR程序。那个8位指针将会来自PIC2

Programmable Interrupt Controller's Addresses

可编程中断控制器的地址

The two PIC's found in an IBM compatible system are initialized via BIOS thus you don't have to worry about all of their registers. However for some people, who have inquisitive (好奇的)minds(思想) the following information may come in some use or maybe you want to (re)program a BIOS? Below is a table of all the command words of the 8259 and compatible Programmable Interrupt Controller. The Top Table shows the Addresses for the PIC1, while the bottom table shows addresses for PIC2.

在一台IBM兼容系统上设立的两个PIC通过BIOS初始化,因此你不必担心所有的寄存器。然而对于某些人,他们有些好奇的想法,想使用以下信息,或者可能你想重新编一个BIOS?下面是一张8259的所有命令字的表,兼容可编程中断控制器。上面的表显示了PIC1的地址,下面的表显示了PIC2的地址。

Address Read/Write Function

20h     Write      Initialization Command Word 1 (ICW1)

Write      Operation Command Word 2 (OCW2)

Write      Operation Command Word 3 (OCW3)

Read       Interrupt Request Register (IRR)

Read       In-Service Register (ISR)

21h     Write       Initialization Command Word 2 (ICW2)

Write      Initialization Command Word 3 (ICW3)

Write      Initialization Command Word 4 (ICW4)

Read/Write  Interrupt Mask Register (IMR)

Table 4 : Addresses/Registers for PIC1

地址 / 操作

20h 初始命令字1ICW1

操作命令字2OCW2

操作控制字3OCW3

中断请求寄存器(IRR

中断服务寄存器(In-Service Register)(ISR

21h 初始命令字2ICW2

       初始命令字3ICW3

          初始命令字4ICW4

       / 中断屏蔽寄存器(IMR

4PIC1寄存器/地址

PIC2 Addresses . . .

Address Read/Write       Function

A0h    Write             Initialization Command Word 1 (ICW1)

Write             Operation Command Word 2 (OCW2)

Write            Operation Command Word 3 (OCW3)

Read              Interrupt Request Register (IRR)

Read             In-Service Register (ISR)

A1h    Write              Initialization Command Word 2 (ICW2)

Write             Initialization Command Word 3 (ICW3)

Write             Initialization Command Word 4 (ICW4)

Read/Write        Interrupt Mask Register (IMR)

Table 5 : Addresses/Registers for PIC2

地址 / 操作

A0h                  初始命令字1ICW1

                        操作命令字2OCW2

                        操作命令字3OCW3

                        中断请求寄存器(IRR

                        中断服务寄存器(ISR

A1h                  初始命令字2ICW2

                        初始命令字3ICW3

                        初始命令字4ICW4

              /     中断屏蔽寄存器(IMR

5PIC2地址/寄存器

 

Initialization Command Word 1 (ICW1)

初始化命令字1ICW1

If the PIC has been reset, it must be initialized with 2 to 4 Initialization Command Words (ICW) before it will accept and process Interrupt Requests. The following selection outlines the four possible Initialization Command Words.

如果PIC被重置,在它接受和处理中断请求前必须使用初始化命令字(ICW24初始化。以下选择(selection)列出了四个可能的初始化命令字。

Bit(s) Function

7: 5 Interrupt Vector Addresses for MCS-80/85 Mode.

4 Must be set to 1 for ICW1

3 1 Level Triggered(引发) Interrupts

0 Edge Triggered Interrupts

2 1 Call Address Interval of 4

0 Call Address Interval of 8

1 1 Single PIC

0 Cascaded(串级) PICs

0 1 Will be Sending ICW4

0 Don't need ICW4

Table 6 : Initialization Command Word 1 (ICW1)

 

功能

7 5  MCS-80/85模式中断向量地址

4  ICW1必须设置为1

3  1 电平引发中断

0 边沿引发中断

2  1  4间隔调用地址

   0  8间隔调用地址

1  1  单一PIC

      0  串级PIC

0  1  将发送ICW4

   0  不需要ICW4

6:初始化命令字1ICW1

 

The 8259 Programmable Interrupt Controller, offers many other features which are not used in the PC. It also offers support for MCS-80/85 microprocessors. All we have to be aware of being PC uses, is if the system is running in single mode (One PIC) or if in Cascaded Mode (More than one PIC) and if the Initialization Command Word 4 is needed. If no ICW4 is used, then all of it's bits will be set to 0. As we are using it in 8086 mode, we must send a ICW4.

8259可编程中断控制器,提供了很多PC机中没有使用的特征。它还提供了MCS-80/85微处理器的支持。我们所有需要注意的PC使用使用的是是否系统运行在单模式(一个PIC)下,或是否在串级模式下(不止一个PIC)还有是否需要初始化命令字4。如果不使用ICW4,那么它的所有位都被设为0。因为我们在8086模式下使用它,我们必须发送一个ICW4

Initialization Command Word 2 (ICW2)

初始化命令字2ICW2

Bit 8086/8080 Mode MCS 80/85 Mode

7 I7 A15

6 I6 A14

5 I5 A13

4 I4 A12

3 I3 A11

2 - A10

1 - A9

0 - A8

Table 7 : Initialization Command Word 2 (ICW2)

 

8086/8080 模式 MCS 80/85 模式

7 I7 A15

6 I6 A14

5 I5 A13

4 I4 A12

3 I3 A11

2 - A10

1 - A9

0 - A8

7:初始化命令字2ICW2

 

Initialization Command Word 2 (ICW2) selects which vector information is released onto the bus, during the 2nd INTA Pulse. Using the 8086 mode, only bits 7:3 need to be used. This will be 00001000 (0x08) for PIC1 and 01110000 (0x70) for PIC2. If you wish to relocate the IRQ Vector Table, then you can use this register.

Initialization Command Word 3 (ICW3)

初始化命令字3ICW3

There are two different Initialization Command Word 3's. One is used, if the PIC is a master, while the other is used for slaves. The top table shows the ICW3 for the master.

Bit Function

7 IR7 is connected to a Slave

6 IR6 is connected to a Slave

5 IR5 is connected to a Slave

4 IR4 is connected to a Slave

3 IR3 is connected to a Slave

2 IR2 is connected to a Slave

1 IR1 is connected to a Slave

0 IR0 is connected to a Slave

Table 8 : Initialization Command Word 3 for Master PIC (ICW3)

And for the slave device, the ICW3 below is used.

Bit(s) Function

7 Reserved. Set to 0

6 Reserved. Set to 0

5 Reserved. Set to 0

4 Reserved. Set to 0

3 Reserved. Set to 0

2 : 0 Slave ID

000 Slave 0

001 Slave 1

010 Slave 2

011 Slave 3

100 Slave 4

101 Slave 5

110 Slave 6

111 Slave 7

Table 9 : Initialization Command Word 3 for Slaves (ICW3)

Initialization Command Word 4 (ICW4)

初始化命令字4ICW4

Bit(s) Function

7 Reserved. Set to 0

6 Reserved. Set to 0

5 Reserved. Set to 0

4 1 Special Fully Nested Mode

0 Not Special Fully Nested Mode

3 : 2 0x Non - Buffered Mode

10 Buffered Mode - Slave

11 Buffered Mode - Master

1 1 Auto EOI

0 Normal EOI

0 1 8086/8080 Mode

0 MCS-80/85

Table 10 : Initialization Command Word 4 (ICW4)

Once again, many of these are special functions not used with the 8259 PIC in a PC. We don't use, Special Fully Nested(嵌套的) Mode, thus this bit is set to 0. Likewise(同样) we use non-buffered mode and Normal EOI's thus all these corresponding bits are set to 0. The only thing we must set is 8086/8080 Mode which is done using Bit 0.

Operation Control Word 1 (OCW1)

操作控制字1OCW1

Once all the required Initialization Command Words have been sent to the PIC, then you can send Operation Control Words, in any order and at any time during the PIC's operation. The Operation Control Words are shown in the next sections.

一旦所有的所需的初始化命令字都已发送到PIC,你就可以以任何顺序在PIC运行的任何时间发送操作控制字。下面的章节显示了操作控制字。

Bit PIC 2      PIC 1

7  Mask IRQ15 Mask IRQ7

6  Mask IRQ14 Mask IRQ6

5  Mask IRQ13 Mask IRQ5

4  Mask IRQ12 Mask IRQ4

3  Mask IRQ11 Mask IRQ3

2  Mask IRQ10 Mask IRQ2

1   Mask IRQ9 Mask IRQ1

0   Mask IRQ8 Mask IRQ0

Table 11 : Operation Control Word 1 (OCW1)

 

PIC2             PIC1

7  屏蔽 IRQ15 屏蔽IRQ7

6  屏蔽 IRQ14 屏蔽IRQ6

5  屏蔽 IRQ13 屏蔽IRQ5

4  屏蔽 IRQ12 屏蔽IRQ4

3  屏蔽 IRQ11 屏蔽IRQ3

2  屏蔽 IRQ10 屏蔽 IRQ2

1   屏蔽 IRQ9 屏蔽 IRQ1

0   屏蔽 IRQ8 屏蔽 IRQ0

11:操作控制1OCW1

 

Operation Control Word 1, shown above is used to mask the inputs of the PIC. This has already been discussed, earlier in this article.

上面显示的操作控制字1是用来屏蔽PIC的输入。这在本文前已经讨论过了。

Operation Control Word 2 (OCW2)

操作控制字2OCW2

Bit(s) Function

7:5 000 Rotate in Auto EOI Mode (Clear)

001 Non Specific EOI

010 Reserved

011 Specific EOI

100 Rotate in Auto EOI Mode (Set)

101 Rotate on Non-Specific EOI

110 Set Priority Command (Use Bits 2:0)

111 Rotate on Specific EOI (Use Bits 2:0)

4 Must be set to 0

3 Must be set to 0

2 : 0 000 Act on IRQ 0 or 8

001 Act on IRQ 1 or 9

010 Act on IRQ 2 or 10

011 Act on IRQ 3 or 11

100 Act on IRQ 4 or 12

101 Act on IRQ 5 or 13

110 Act on IRQ 6 or 14

111 Act on IRQ 7 or 15

Table 12 : Operation Control Word 2 (OCW2)

功能

7 5  000 在自动EOI模式下轮转(清空)

          001 未指定的EOI

       010 保留

          011 指定的EOI

          100 在自动EOI模式下轮转(置位)

          101 在未指定EOI上轮转

          110 设置优先级命令(使用位2:0

          111 在指定EOI上轮转(使用位2:0

       4 必须设置为0

       3 必须设置为0

       2:0 000 作用域IRQ08

              001 作用于IRQ19

              010 作用于IRQ210

              011 作用于IRQ311

              100 作用于IRQ412

              101 作用于IRQ513

              110 作用于IRQ614

              111 作用于IRQ715

12:操作控制字2OCW2

Operation Control Word 2 selects how the End of Interrupt (EOI) procedure works. The only thing of interest to us in this register is the non-specific EOI command, which we must send at the end of our ISR's.

操作控制字2选择中断结束程序如果工作。在这个寄存器中对我们有用的仅仅是未指定EOI命令,这是我们在ISR结束时必须发送的。

Operation Control Word 3 (OCW3)

操作控制字3OCW3

Bit(s) Function

7 Must be set to 0

6 : 5 00 Reserved

01 Reserved

10 Reset Special Mask

11 Set Special Mask

4 Must be set to 0

3 Must be set to 1

2 1 Poll Command

0 No Poll Command

1 : 0 00 Reserved

01 Reserved

10 Next Read Returns Interrupt Request Register

11 Next Read Returns In-Service Register

Table 13 : Operation Control Word 3 (OCW3)

功能

7 必须设置为0

65 00 保留

       01 保留

       10 重置专门的屏蔽位

       11 设置专门的屏蔽位

4   必须设置为0

3   必须设置为1

2  1 轮询命令

   0 非轮询命令

1:0 00 保留

   01 保留

   10 下次读取返回中断请求寄存器

   11 下次读取中断服务寄存器

13:操作控制字(OCW3

Bits 0 and 1 are of the most significant to us, in Operation Control Word 3. These two bits enable us to read the status of the Interrupt Request Register (IRR) and the In-Service Register (ISR).

在操作控制字3中位01对我们来说是最重要的。这两个位可以使我们读取中断请求寄存器(IRR)和中断服务寄存器(ISR)的状态。

This is done by setting the appropriate bits correctly as above, and reading the register at the Base Address.

通过正确的设置上面的合适的位和读取基址寄存器做到这一点。

For example if we wanted to read the In-Service Register (ISR), then we would set both bits 1 and 0 to 1. The next read to the base register, (0x20 for PIC1 or 0xA0 for PIC2) will return the status of the In-Service Register.

例如,如果我们想要读取中断服务寄存器,那么我们将位01都设置为1。下一次读取的基址寄存器(PIC1对应0x20PIC2对应0xA0)将会返回中断服务寄存器的状态。

 

这个文章是从看雪论坛下下来的,www.pediy.com

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值