ELEC2630 EMBEDDED SYSTEMS THEORY Lecture 7: Interrupts
INTERRUPTS • INTERRUPTS change the flow of the program but normally in response to a hardware event • This could be a signal received from outside the microcontroller or from one of the peripherals inside the device itself • The microcontroller saves the address of the next instruction on the stack before changing the program counter to the address of the interrupt routine in memory • This can be fixed or partly supplied by the interrupting device • A special type of return is used to go back to the address saved on the stack
Interrupts and ‘C’ • ‘C’ was initially designed before micro-controllers or any small computing device capable of running the large amount of code space required • All the machines that ‘C’ ran on, Mainframe or mini-computers, had an operating system which handled all the low level hardware interfacing tasks so interrupts were dealt with at that level • Later, when the idea of cross-compiling to the machine code for a small device was developed, each compiler writer devised their own extension to ‘C’ to carry out the task
C Interrupt Handling Example • If the micro-controller device had only one address for the interrupt code (often called an interrupt vector) then only one C function could be associated with interrupts • At the assembler level the actual place in memory can be set by an “origin” command but C does not normally use such direct methods • A very common method is to use a Keyword within the normal function definition to indicate that this function should be associated with the interrupt. • The C compiler would then use this message to arrange for the machine code to be generated for the correct address for the hardware
Interrupt Handling • A solution used by the C compilers supplied by Htsoft for PIC micro-controllers uses the keyword “interrupt” • Note the function using this keyword must be of type “void” because there is no mechanism for an interrupt function to return a value directly, i.e. You cannot have a return(value); as part of the interrupt function • The function cannot receive a value as input as it is not called from anywhere within the normal code • void interrupt 2630int (void); would be the form of the function prototype for an interrupt routine
Interrupt handling • How do we handle a number of different interrupts when only one interrupt location exists, and thus only one interrupt function is allowed? • At the assembler level the interrupts can be checked individually, so C code using similar methods can be used provided the code is all inside the one function • A number of functions could be “called” from within that function, each dealing with a different interrupt if required, although there would be a time penalty in using this approach
Interrupt Handling • Each interrupt sets a flag when it occurs and interrupts the micro-controller if it is enabled to do so • These flags are individual bits within a single variable • A test of a bit could determine whether to call the function for that interrupt, as the flag is normally cleared during setup, so a logic 1 bit would indicate that interrupt has occured and that the particular function is needed to “service” it. This is the term normally used for code responding to an interrupt
Interrupt Code example • Here is an example where the flags are in a variable called int-flags • Void interrupt 2630int () { if(int-flags & 1) void int1(); if(int-flags & 2) void int2(); }
Points to note • C compiler may have methods for manipulating individual bits in a variable • The method shown, “bitwise and” will work with any compiler • The htsoft compiler for the F18 devices is very efficient and will check if the task being done in the C has a direct counterpart in the assembler, and if so it will use it • In the case shown a “BTFSC int-flags,1” would be a direct replacement of the first part of the IF and a “GOTO _int1” is the rest
Interrupt Priorities • The priority defines the order in which the interrupts are serviced if more than one occurs at once • How is the priority set in the example on the last slide? • One hardware method employed in microcontrollers is the use of multiple interrupt vectors where the vector called by the interrupt sets the priority • Higher priority interrupts can interrupt a lower priority interrupt whilst it is executing • The stack is used to take care of this example of “nesting”
Problems in this approach • Context switching, how do we prevent the registers being used in the first interrupt being corrupted by reuse in the second interrupt • Multiple vectors mean more than one C function can use an interrupt so how is C extended again to cope with this new situation • These are questions to be answered in the next lecture