Handling interruptions under Linux

Alex Rojo (alex@picmatic.es)
Fri, 27 Jun 1997 10:46:46 +0200


Hi, linuxers!

I'm trying to do a serial communications program. The problem is that
the hardware I have to connect to does not use and standard
communications protocol and i nedd to handle serial interruption and
also i need a backgroud timer (milisg resolution) that checks CTS line.
I have it running under DOS. This is part of the DOS source. Can anybody
help me? How can I handle interruptions in Linux?

TIA

ALEX ROJO

******************************************************************************************************************************************************************************************
void interrupt(*oldvects[2])();

// Buffer circular de recepcion

static char rxdbuf [SBUFSIZ];

unsigned int startbufrxd = 0;
unsigned int endbufrxd = 0;

static char indx_test = 0x00;

// Variables asociadas al timmer.

unsigned timer_serial = 0; // Temporizador para el canal
serie
unsigned cts = 0; //
Imagen de estado de la linea CTS

char buff_temp [250];

/****************************************************************************
void interrupt hand_tim (void)
-----------------------------------------------------------------------------
Periodic interruption handler.
****************************************************************************/
#ifdef TIMER
void interrupt hand_tim (void)
#else
void hand_tim (void)
#endif
{

/* Temporizador */

if (timer_serial)
timer_serial --;

// Detect trigger of CTS

cts = inportb (portbase+MSR) & CTS;
}

/******************************************************************************
Communication interrupt handler. Read serial channel and put it
in read
buffer ccbuf.
******************************************************************************/
void interrupt com_int (void) {

char c, status_int;

disable();

// Quien ha generado la interrupcion

status_int = inport (portbase + IIR) & RX_MASK;

// Interrupcion generada por el recepctor ?

if (status_int & RX_ID) {
if (((endbufrxd + 1) & SBUFSIZ - 1) == startbufrxd)
SError = BUFOVFL;
c = inportb (portbase + RXR);
rxdbuf [endbufrxd++] = c;
endbufrxd &= SBUFSIZ - 1;
}

// La interrupcion es producida por el Transmisor

// if (status_int & TX_ID) {
// }

// Indicar al hardware el final de la interrupcion */

outportb (ICR,EOI);
enable ();
}
/******************************************************************************
Set my communications interrup handler.
******************************************************************************/
void setvects (void)
{
oldvects[0] = getvect(0x0B);
oldvects[1] = getvect(0x0C);
setvect(0x0B, com_int);
setvect(0x0C, com_int);
}

/******************************************************************************
Restore old interrupt vectors
******************************************************************************/
void resvects (void)
{
setvect(0x0B, oldvects[0]);
setvect(0x0C, oldvects[1]);
}

/******************************************************************************
Enable interruptions
******************************************************************************/
void i_enable (int pnum)
{
int c;

disable();
// c = inportb (portbase + MCR) | MC_INT ;
// outportb (portbase + MCR, c);

outportb (portbase + MCR, 0x0C);
outportb (portbase + IER, (RX_INT | TX_INT));
c = inportb (IMR) & (pnum == COM1 ? IRQ4 : IRQ3);
outportb (IMR, c);
enable ();
}

/******************************************************************************
Disable interruptions
******************************************************************************/
void i_disable(void)
{
int c;

disable();
c = inportb(IMR) | ~IRQ3 | ~IRQ4;
outportb(IMR, c);
outportb(portbase + IER, 0);
c = inportb(portbase + MCR) & ~MC_INT;
outportb(portbase + MCR, c);
enable();
}
*******************************************************************************************