Reloj hardware: Intel 8253

De Wiki de Sistemas Operativos
Saltar a: navegación, buscar

PIT (Programmable Interval Timer)

En primer lugar, es necesario saber qué es un PIT . Un PIT es un contador que dispara una interrupción cuando alcanza la cuenta programada. Pueden ser de dos tipos:

· One-shot: disparan una interrupción y dejan de contar.

· Periódicos: disparan una interrupción y restauran el contador para volver a repetir el ciclo.

Estas interrupciones son aprovechadas para lanzar actividades del kernel que requieren periodicidad.

Un poco de Historia: IBM PC y el Intel 8253.

El Intel 8253 es un PIT diseñado inicialmente para el Intel 8080 y el 8085, y posteriormente usado por el IBM y sistemas x86.

El IBM PC tenía un generador de reloj, el Intel 8284, que contaba con un cristal de cuarzo (1). Gracias a un circuito oscilador se obtenía una frecuencia de 14’31818…MHz (1260/88). El ciclo de trabajo de procesador, el Intel 8088, era de un 33%, dando como resultado una frecuencia de 4’77MHz. Este procesador soportaba hasta 5MHz (en cuyo caso necesitaría un cristal de 15MHz), no obstante, al dividir 14’31818/4 se obtenía 3’5795MHz, que era la frecuencia de la tarjeta de video, lo cual suponía un importante ahorro económico. Finalmente, la frecuencia del procesador se dividía entre 4, dando como resultado 1’1931818...MHz, que es la frecuencia utilizada por el PIT Intel 8253. El IBM PC utilizada E/S separada o independiente, luego era necesario instrucciones especiales (outb, outw…) para su implementación.


Intel82531.png
82532.png


El Intel 8253 tenía tres contadores independientes que podían programarse en seis modos diferentes. En el IBM PC:

· En el contador 0, se dividía la frecuencia entre 216, lo cual producía una señal de 18’207 Hz, es decir, 18 interrupciones por segundo, que eran utilizadas para mantener la hora del sistema. Este contador estaba conectado al IRQ 0 del controlador de interrupciones.

· En el contador 1, se dividía la frecuencia entre 18 y se utilizaba para refrescar la memoria RAM. Estaba conectado con el controlador DMA.

· En el contador 2, el cociente de la frecuencia entre 1 y 216 era usado para generar tonos por el altavoz e incluso, generar tonos que representasen 0s y 1s para grabar cassettes.

Estos contadores se programaban con el Control Word Register. Los contadores estaban situados en las direcciones 0x40, 0x41 y 0x42, mientras que el CWR estaba en la 0x43.

La palabra de control usada por el CWR tenía un tamaño de 8 bits (x7x6x5x4x3x2x1x0) :


x0 - Modo BCD:

0 - El contador trabajará en formato binario de 16 bits.

1 - El contador trabajará en formato BCD con cuatro dígitos decimales.

x3x2x1 - Modo de operación para el contador:

000 - Modo 0. Interrumpe al terminar el conteo.

001 - Modo 1. Disparo programable.

X10 - Modo 2. Generador de impulsos.

X11 - Modo 3. Generador de onda cuadrada.

100 - Modo 4. Strobe disparado por software.

101 - Modo 5. Strobe disparado por hardware.

x5x4 - Modo de acceso (lectura/escritura) para el valor del contador:

00 - Counter Latch. El valor puede ser leído de la manera en que fue ajustado previamente. El valor es mantenido hasta que es leído o sobreescrito.

01 - Lee (o escribe) solo el byte menos significativo del contador (bits 0-7)

10 - Lee (o escribe) solo el byte más significativo del contador (bits 8-15)

11 - Primero se lee (o escribe) el byte menos significativo del contador, y luego el byte más significativo.

x7x6 - Selección del contador:

00 - Se selecciona el contador 0.

01 - Se selecciona el contador 1.

10 - Se selecciona el contador 2.

11 - No usado. (solo hay 3 contadores).


(1): El cuarzo es un material piezoeléctrico, es decir, al ser sometido a tensiones mecánicas su masa se polariza, lo cual genera una diferencia de potencial.

Timer.c en Xv6

El número de interrupciones por segundo marca la precisión de nuestro reloj. Con el siguiente código en C conseguimos crear una interrupción cada centésima de segundo:

// Intel 8253/8254/82C54 Programmable Interval Timer (PIT).

// Only used on uniprocessors;

// SMP machines use the local APIC timer.

#include "types.h"

#include "defs.h"

#include "traps.h"

#include "x86.h"

#define IO_TIMER1       0x040           // 8253 Timer #1

// Frequency of all three count-down timers;

// (TIMER_FREQ/freq) is the appropriate count

// to generate a frequency of freq Hz.

#define TIMER_FREQ      1193182 

#define TIMER_DIV(x)    ((TIMER_FREQ+(x)/2)/(x))

#define TIMER_MODE      (IO_TIMER1 + 3) // timer mode port

#define TIMER_SEL0      0x00    // select counter 0

#define TIMER_RATEGEN   0x04    // mode 2, rate generator

#define TIMER_16BIT     0x30    // r/w counter 16 bits, LSB first

void timerinit(void)
{

  // Interrupt 100 times/sec.

  outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
  outb(IO_TIMER1, TIMER_DIV(100) % 256);
  outb(IO_TIMER1, TIMER_DIV(100) / 256);
  picenable(IRQ_TIMER);

}

Fuentes

· http://www.cpcwiki.eu/imgs/e/e3/8253.pdf Datasheet del Intel 8253

· https://github.com/NewbiZ/xv6/tree/848b3d4fa02c7c4ebed0a8e79cc52fc8273b57e6 Código XV6

· https://es.wikipedia.org/wiki/Temporizador_programable_de_intervalos

· https://es.wikipedia.org/wiki/Intel_8253

11.7 Ejercicios Gestión L/E