User’s Manual
GSM35
28
RTD Finland Oy
call to the same DOS function X, then function X is essentially being called
while active. Such cases will cause the computer to crash. DOS does not
support such operations. The general rule is that do not call any functions
that use the screen, read keyboard input or any file I/O routines, these
should not be used in ISR's.
The same problem of re-entrancy also exists for many floating-point
emulators. This effectively means that you should also avoid floating point
mathematical operations in your ISR.
Note that the problem of reentrancy exists, no matter what programming
language you use. Even, if you are writing your ISR in Assembly language,
DOS and many floating point emulators are not re-entrant. Of course there
are ways to avoid this problem, such as those which activate when your
ISR is called. Such solutions are, however, beyond the scope of this
manual.
The second major concern when writing ISR's is to make them as short as
possible in term of execution time. Spending long times in interrupt service
routines may mean that other important interrupts are not serviced. Also, if
you spend too long in your ISR, it may be called again before you have
exited. This will lead to your computer hanging up and will require a reboot.
Your ISR should have the following structure:
•
Push any processor registers used in your ISR.
•
Put the body of your routine here
•
Clear the interrupt bit by reading GSM35 RXD register
•
Issue the EOI command to the 8259 by writing 20h to 20h
•
Pop all registers. Most C compilers do this automatically
The following C example shows what the shell of your ISR should be like:
/*-------------------------------------------------------------------------------
| Function:
new_IRQ_handler
| Inputs:
Nothing
| Returns:
Nothing
|-------------------------------------------------------------------------------*/
void interrupt far new_IRQ_handler(void)
{
IRQ_flag = 1;
// Indicate to process interrupt has occurred
{
// Your program code to read UART
// read to a data buffer for example:
Guc_buffer[Gi+] = inp(gi_SERIAL_DATA);
}
outp(0x20, 0x20);
// Acknowledge the interrupt controller
}