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: 1802
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. 2025 )