2
\$\begingroup\$

During my study of Atmega328 datasheet I found that each interrupt vector occupies two addresses and after searching i can not find why that.

That is a screen shot from atmega328p datasheet page 82

enter image description here

\$\endgroup\$
  • 1
    \$\begingroup\$ I don't have the spec in front of me, but it's quite common for addresses to be larger than a single memory word. Each interrupt vector stores an address, so an address likely takes up two words of memory. \$\endgroup\$ – Pete Becker Apr 14 '17 at 13:36
5
\$\begingroup\$

The unit size of the vector table depends on what chip you use. For example ATTiny chips use 2 bytes (1 instruction) for each vector in the table.

The reason for allowing multiple instructions worth on the larger processors is to allow for the use of larger instructions.

For an AVR, the RJMP instruction is a 2 byte instruction for relative jump - however it can only access +/-4kB displacement from the vector table. This is fine on the smaller processors with <8kB of Flash as it allows ISRs (Interrupt Service Routines) to be placed anywhere within the flash memory. However for larger AVRs such as the 32kB flash ATMega328, this is not enough (*).

To access the full flash space you need to use the JMP instruction. This is a direct jump which allows you to access up to 4MB of flash. However the JMP instruction is actually a 4 byte instruction. In order to use these in the vector table you need to allow 2 instruction words for each vector. And this is just what they do.

It is still perfectly possible to use RJMP or any other single word instruction within a two word vector table. All you do is add an additional NOP after it to pad out the instruction to two words.

Additionally you don't necessarily have to jump anywhere. Imagine your ISR was required to do nothing more than set a bit in an IO register. On an AVR you can if the register is within range you can use the SBI or CBI instruction to do this. Because that doesn't have any side-effects on the ALU flags, you can within a two instruction vector table construct your entire ISR (SBI instruction followed by RETI instruction) and save all the overhead of jumping to an ISR.


(*) It is actually possible, though slower, to use what are called "trampolines". This is basically a case of placing a single JMP instruction in the flash within +/-4k displacement from the vector table. The vector table contains an RJMP instruction that jumps to the nearby JMP instruction which in turn jumps to anywhere in the flash.

\$\endgroup\$
  • \$\begingroup\$ According to your note(*), it is may be in our case that the first address is used to store the interrupt vector and the second address is used to store the actual address of Interrupt Service Routine ? \$\endgroup\$ – M Y Apr 14 '17 at 14:53
  • \$\begingroup\$ @mostafayasin No, if a JMP instruction is used, the address of the ISR is embedded within the instruction, it's just that the instruction takes up 4bytes. If a trampoline is used on devices with 2byte/vector in the table, then the RJMP instruction is in the vector table which stores the relative address of the JMP instruction which is placed somewhere else in the memory. The JMP instruction still has the address of the ISR embedded within it. \$\endgroup\$ – Tom Carpenter Apr 14 '17 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.