SDCC allows interrupt service routines to be coded in C, with some extended keywords.
void timer_isr (void) __interrupt (1) __using (1)The optional number following the interrupt keyword is the interrupt number this routine will service. When present, the compiler will insert a call to this routine in the interrupt vector table for the interrupt number specified. If you have multiple source files in your project, interrupt service routines can be present in any of them, but a prototype of the isr MUST be present or included in the file that contains the function main. The optional (8051 specific) keyword using can be used to tell the compiler to use the specified register bank when generating code for this function. Interrupt service routines open the door for some very interesting bugs:
If an interrupt service routine changes variables which are accessed by other functions these variables have to be declared volatile. See http://en.wikipedia.org/wiki/Volatile_variable .
If the access to these variables is not atomic
(i.e. the processor needs more than one instruction for the access
and could be interrupted while accessing the variable) the interrupt
must be disabled during the access to avoid inconsistent data.
The return address and the registers used in the interrupt service routine are saved on the stack so there must be sufficient stack space. If there isn't variables or registers (or even the return address itself) will be corrupted. This stack overflow is most likely to happen if the interrupt occurs during the ''deepest'' subroutine when the stack is already in use for f.e. many return addresses.
A special note here, int (16 bit) and long (32 bit) integer division,
multiplication & modulus and
floating-point operations are implemented
using external support routines. If an interrupt service routine needs
to do any of these operations then the support routines (as mentioned
in a following section) will have to be recompiled using the --stack-auto
option and the source file will need to be compiled using the --int-long-reent
compiler option.
Calling other functions from an interrupt service routine is not recommended,
avoid it if possible. Note that when some function is called from
an interrupt service routine it should be preceded by a #pragma nooverlay
if it is not reentrant. Furthermore nonreentrant functions should
not be called from the main program while the interrupt service routine
might be active. They also must not be called from low priority interrupt
service routines while a high priority interrupt service routine might
be active. You could use semaphores or make the function critical
if all parameters are passed in registers.
Next: 3.8.2 MCS51/DS390 Interrupt Service Up: 3.8 Interrupt Service Routines Previous: 3.8 Interrupt Service Routines Contents Index 2008-02-29 |