# How to avoid over-writing to Interrupt Handler?

#### electroRF

##### Member
Hi,
In the 8051, the Vector Address of the interupt handler of each Interrupt are 8 bytes away from each other in ROM Memory (they are kept in ROM, right? not in RAM?)

I'm writing in C, not in Assembler.

How can you avoid writing more than 8 bytes to the Interrupt Handler of an interrupt?

Thank you.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
You don't.... When you write an ISR you change the interrup vector to point to another location..

The interrupt vector normally contains a return ( from interrupt ) you write your interrupt code ( somewhere in the code space ) and then put the address of you interrupt in the vector... You should look at a few assembly ISR routines so you can see...

#### electroRF

##### Member
Hi Ian,
Thank you very much.

The Vector Address is given in the datasheet, and it is not said how you can change it.

for example, PORT0 input Interrupt handler is at 0x6B in Code Memory.

you say that one should change the vector address, so that when PORT0 gets an interrupt, the CPU will put other address than 0x6B in the Program Counter?

I don't think the datasheet says how to do it.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Here's a little asm code

See how the address of the ISR is placed at the vector to the ISR routine..
Code:
    sjmp    main

org    0x0B            ; Timer 0 vector
ljmp    ISR            ; New vector is written here ISR = function address

org 0x30            ; Program starts
main:
mov    TMOD,0x1        ; Timer 1
mov    TH0,#0x4C
setb    TR0
mov    IE,#0x82        ; IE = on and ET0 = on

while:    sjmp    while

ISR:    setb    P1.1            ; just do something
clr    P1.1
mov    TH0,#0x4C        ; Reset timer
mov    TL0,#0x00
reti
end

#### misterT

##### Well-Known Member
The Vector Address is given in the datasheet, and it is not said how you can change it.
You can't change it. You can program a jump statement to any location (ISR function) you want. If you program with C, then you must have some framework that takes care of all the details.. you can define an interrupt service routine (ISR) and the compiler takes care of the details.

#### electroRF

##### Member
Thank you very much NSA, Ian and T !

And also thanks to Jon Wilder who helped me out as well.

You can't change it. You can program a jump statement to any location (ISR function) you want. If you program with C, then you must have some framework that takes care of all the details.. you can define an interrupt service routine (ISR) and the compiler takes care of the details.
The information of how the ISR should be called, i.e. how to call the PORT0 ISR for the compiler to know to add a jumo statement in 0x006B to that ISR - is this info found in the Compiler?

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Ok! What C compiler are you going to use... The setup is different from compiler to compiler, that's why I posted an assembler code example....

I am using SDCC and VSMStudio from labcenter!!

#### electroRF

##### Member
Hi Ian,

I'm going to use IAR C Compiler, and wondering if in general, a C progrmmer should look into the compiler for how he should name the ISR function?

That is to ensure that the Compiler will direct the Prog.Cnt to the programmer's ISR function when a certian interrupt occurs.

#### misterT

##### Well-Known Member
Read IAR's manual.... Usually the interrupt function has to be followed by the Interrupt number.
Exactly. You are on the mercy of the compiler and how well it is documented.

I like what avr-libc says about interrupts:
"It's nearly impossible to find compilers that agree on how to handle interrupt code. Since the C language tries to stay away from machine dependent details, each compiler writer is forced to design their method of support."
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

#### electroRF

##### Member
friends,
I have a question please on interrupt latency.

I know that its the time (measured in machine cycles) from the cycle in which the interrupt occurred to the first cycle of the ISR,

which can be quite "long" in real-time applications, as it could take ~4 cycles for the longest instrcution to complete, then +1 cycle for checking priorities, then +2 cycles to push Prog.Cnt to stack, then another cycle or two to check for the Vector Address and move it into the Prog.Cnt - Total of ~9 cycles.

how can one reduce the latency?

I thought about using polling, but if you poll for every type of interrupt, wouldn't it increase the latency?

Thank you.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
It's normally good practice to keep the interrupt as short as you can.. However sometimes it's not possible.

On the 8051 you have interrupt priority, you can interrupt an interrupt, therefore you can allow one interrupt to be long as another can cut in when it needs to...

If you only ever use one external interrupt... As long as you are done well before the next event occurs there is no mind.. However!!! If you have an interrupt that takes a good majority of the CPU time then code in your main suffers and can't get on with it's task....

If at all possible, use a software flag within your interrupt, then service it outside the interrupt.. For example when using the serial module... When you receive a character, place it in a buffer, exit the ISR, when the termination character has been received set a software flag so the main knows the buffer is full....

#### NorthGuy

##### Well-Known Member
You normally plan your interrupt handling in such a way that it is Ok for the interrupt to be postponed. If you don't plan it like that, you cannot disable any interrupts even for a short time, which is impossible in all but most simple situations. Therefore, latency doesn't really matter. You need to plan your actions so that you don't disable interrupts for longer than certain amount of time, and you process your interrupts fast by moving all the hard work to the main routine. You must be prepared for the situations where things have changed between the time when the interrupt was initiated and time where you finally got to process it.

#### electroRF

##### Member
Hi guys,
Thanks!
I learned a lot from your posts

I'd like to emphasize a point, which I read in several spots.
for example, it was written in this lecture:
Polling Vs. Interrupts
1. Interrupts win if processor has other work to do and event response time is not critical
2. Polling can be better if processor has to respond to an event ASAP
2.1 May be used in device controller that contains dedicated secondary processor
i.e. it is claimed that polling produce lower latency, but perhaps it is only in the case when a device controller has a dedicated secondary processor.

Otherwise, the CPU needs to poll every interrupt which may increase the latency rather than decreasing it.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
You would use polling in a simple code... Ie:... If you are waiting for an input!!!

while(P1,1); // Wait here until port 1 pin 1 goes low... This is the best way to do this... However if your code is more complex and you have other things to process, then an interrupt is needed...

#### electroRF

##### Member
You would use polling in a simple code... Ie:... If you are waiting for an input!!!

while(P1,1); // Wait here until port 1 pin 1 goes low... This is the best way to do this... However if your code is more complex and you have other things to process, then an interrupt is needed...

Got you
Thanks.

#### NorthGuy

##### Well-Known Member
If you need something ligtning fast then polling is the best. However, if you poll you cannot do anything else, otherwise it won't be fast any more. If feasible, external hardware solutions (e.g. comarators) are even better.

A big plus of the interrupts is that processor may be put in idle or sleep mode and save energy, so your power consumption goes way down.