Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Folosirea interuperilor la calculatoarele IBM PC

Informatica


Folosirea īnteruperilor la calculatoarele IBM PC

Microprocesoul I8086 are un set de 256 vectori de īntreupere, numerotati de la 0 la 255. Fiecare vector are un cod de 4 octeti care reprezinta adresa rutinei de tratarea a īntreruperii (ISR).



Limbajele de nivel īnalt rateaza problema gasirii acestei adrese, pe baza vectorului de īntrerupere.

Īn tabelul urmaor se prezinta īntreruperile din PC care sunt asociate cu nivele IRQ. 131p159b

INT (Hex)

IRQ

Utilizare

System Timer

Tastatura

0A

Redirectare

0B

Serial Com. COM2/COM4

0C

Serial Com. COM1/COM3

0D

Reservat/Placa de Sunet

0E

Floppy Disk Controller

0F

Paralel Com.

Real Time Clock

Reservat

Reservat

Reservat

PS/2 Mouse

Maths Co-Processor

Hard Disk Drive

Reservat

Procesorul 80x86 are doua linii pe care dispozitivele externe le pot folosi pentru semnale de īntrerupere INTerrupt Request si NonMaskable Interrupt.

Daca linia INTR este activa, unitatea centrala executa diferite operatii īn functie de indicatorul de validare a īntreruperilor IF. Daca acesta este sters (īntreruperile semnalate de INTR sunt mascate sau dezactivate), unitatea centrala ignora īntreruperea si executa instructiunea urmatoare. Daca IF este pozitionat, unitatea centrala recunoaste cererea de īntrerupere, opreste executia normala a instructiunilor si preda controlul rutinei de tratare a īntreruperilor. Indicatorul IF poate fi pozitionat sau sters din program.

Pe a doua linie sosesc īntreruperi folosite pentru a anunta evenimentele critice. Acestea (NMI) nu pot fi mascate sau dezactivate si unitatea centrala le ia īn considerare de fiecare data. Intervalul de timp de la sosirea unei īntreruperi pāna la servirea ei depinde de numarul de impulsuri de ceas care au mai ramas sa fie executate din instructiunea curenta.

Īntreruperi interne

Sunt generate īn urma executiei instructiunilor INT sau INTO sau sunt generate automat de unitatea centrala īn anumite conditii (īmpartire cu 0, executie pas cu pas ). Instructiumea INT genereaza o īntrerupere imediat dupa executia sa. Timpul de īntrerupere este codificat īn instructiune, anuntānd unitatea centrala care rutina de tratare a īntreruperii sa o execute.

INTO genereaza o īntrerupere de tip 4 (overflow).

Īntreruperea de tip 0 este generata de unitatea centrala īn cazul īn care īn urma unei instructiuni de īmpartire rezultatul este mai mare decāt destinatia specificata.

Daca TF este pozitionat, unitatea centrala genereaza automat o īntrerupere de tip 1 dupa executia fiecarei instructiuni. Aceasta executie pas cu pas foloseste la depanarea programelor.

Īntreruperea 3 (breakpoint) este dedicata depanarii programelor.

Circuitul pentru contolul īntreruperilor (8259A)

Circuitul manipuleaza pāna la 8 īntreruperi si poate fi cascadata pāna la 64 īntreruperi folosind circuite aditionale. Este interfatata la magistrala de date si la magistrala de control. Genereaza catre procesor semnalul INT . Primeste INTA si cererile de īntrerupere pe liniile IR0-IR7.

Contine registrele :

-Interrupt Request Register (stocheaza cererile de īntrerupere );

-In Service Register (stocheaza īntreruperile care se servesc );

-Interrupt Mask Register (stocheaza masca de īntrerupere), (21H).

Procesul de īntrerupere contine urmatorii pasi :

Una sau mai multe cereri de īntrerupere (IR0-7) trec pe nivelul "high" setānd bitii corespunzatorii din IIR.

8259A evalueaza cererile si trimite INT catre CPU.

CPU accepta īntreruperea raspunzānd cu INTA.

La primirea lui INTA bitul cu cea mai mare prioritate este setat in ISR, iar bitul corespunzator din IRR este resetat. 8259 va lansa o instructiune CALL pe magistrala de date.

CALL va initia 2 semnale INTA.

Pe cele doua semnale INTA, 8259 va trimite vectorul de īntrerupere.

Tabela vectorilor de īntrerupere

Asocierea īntre tipul īntreruperii si rutina de tratare a īntreruperii este facuta prin tabela vectorilor de īntrerupere. Aceasta ocupa prima zona din memorie pornind de la adresa fizica 0 pāna la 1K. Aceasta tabela poate avea pāna la 256 de intrari, cāte una pentru fiecare īntrerupere. Fiecare intrare din tabela este un pointer dublu (4 octeti ) continānd adresa rutinei de tratare a īntreruperii de tipul respectiv. Cuvāntul de la adresa mai mare contine adresa de baza a segmentului care contine rutina, iar cuvāntul de la adresa mai mica contine deplasamentul rutinei fata de īnceputul segmentului. Deoarece fiecare intrare are lungimea de 4 octeti, UC calculeaza locatia unei intrari, a unei īntreruperi prin simpla īnmultire a tipului cu 4.

La sosirea unei īntreruperi, UC salveaza registrul cu indicatorii de stare si control īn stiva si apoi activeaza rutina de tratare a īntreruperii prin executarea unei instructiuni CALL īntre segmente. Adresa de la care se face saltul (adresa rutinei ) este adresa continuta īn tabela vectorilor de īntrerupere la locatia tip*4. UC salveaza adresa instructiunii urmatoare prin īncarcarea registrilor CS si IP īn stiva. Acestia sunt īnlocuiti apoi cu primul, respectiv cu al doilea cuvānt al adresei din tabela. Īn acelasi timp sunt initializati TF si IF. Daca se doreste reactivarea īntreruperilor īn timpul rutinei de tratare a īntreruperii, acesti indicatori trebuiesc repozitionati.

Este bine ca rutina de tratare a īntreruperii sa activeze īntreruperile externe, cu exceptia secventelor critice. Īntreruperile externe dezactivate un timp prea lung se pot pierde.

End Of Interrupt reseteaza bitul setat īn ISR (20H).

Rutinele de tratare a īntreruperilor trebuie sa se termine cu instructiunea IRET. Ea va descarca de pe stiva IP, CS si indicatorii de stare si control (adresa instructiunii urmatoare si indicatorii, īnainte de activarea rutinei de tratare a īntreruperii ).

Programarea īntreruperilor

Borland Turbo C are doua fuctii de biblioteca pentru citirea si modificarea unui vector de īntreruperi. Acestea sunt: setvect() si getvect(). ( iar Microsoft C: _dos_getvect() si _dos_setvect(). )

getvect() are prototipul:

void interrupt(*getvect(int interrupt_no))();

setvect() are prototipul:

void setvect(int interrupt_no, void interrupt(*func)());

Un program care citeste si salveaza adresa unei īntreruperi existente foloseste getvect() astfel:

/* Declara variabila pentru citirea īntreruperii vechi */

void interrupt(*old)(void);

main()

Unde 0x1C este vectorul cautat

Pentru a aloca vectorul de īntrerupere la o noua adresa, care este propria noastra functie, folosim setvect():

void interrupt new(void)

main()

Observatii:

Daca īntreruperea e apelata de evenimente externe, īnainte de a modifica vectorul, este obligatorie invalidarea īntreruperilor prin disable() si apoi revalidarea īntreruperilor dupa schimbarea vectorului folosind enable().

Īnaintea terminarii programului e obligatorie stergerea oricaror modificari facute asupra vectorilor de īntrerupere.

Mascarea

Programatorul poate masca īntreruperi, folosind portul 0x21. Pentru a valida o anumita īntrerupere, se scrie '0' īn bitul corespunzator.

mask=inportb(0x21) & ~0x80;

//Citeste masca curenta. Pune bitul 7 pe '0'

//Lasa ceilalti biti nemodificati

outportb(0x21, mask);

Utilizatorul poate folosi īntreruperea IRQ7. El poate scrie propria sa rutina de tratare a īntreruperii, dar e obligat sa insereze secventa:

outportb(0x20, 0x20);

(EOI )informānd ca īntreruperea a fost tratata.

Exemplu

/* ** Program test interfata seriala **

Folosese o rutina de tratare a intreruperii

Intreruperea e determinata de transmisie

Notam ca am considerat portul serial COM1, 3F8h si am asociat IRQ4.

Nume Adresa in tabel **

IRQ2 0x0a

IRQ4 0x0c

IRQ5 0x0d

IRQ7 0x0f ** */

#include <stdio.h>

#include <bios.h>

#include <dos.h>

#include <conio.h>

#include <string.h>

#define DATA 0x03F8

#define IER DATA+1

#define IIR DATA+2

#define LCR DATA+3

#define MCR DATA+4

#define LSR DATA+5

#define MSR DATA+6

void close_intserv(void);

void int_processed(void);

void open_intserv(void);

void interrupt far intserv(void);

int intlev=0x0c; /* interuperea asociata cu IRQ4 */

int int_occurred = 0 ;

void interrupt far (*oldfunc)();

/* Definitii globale */

int main(void)

close_intserv();

return(0);

void interrupt far intserv(void)

/* Este rutina de tratare a intreruperii */

int_processed();

int_occurred=1;

enable();

void open_intserv(void)

/* valideaza IRQ4. In caz de intrerupere salt la intserv.

** toate intreruperile se invalideaza pe durata acestei functii

Validarea se face la iesire. */

void close_intserv(void)

/* invalideaza IRQ4 */

void int_processed(void)

/* EOI */

Scrieti programul de test din laboratorul precedent, folosind īntreruperile.


Document Info


Accesari: 1771
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )