Pages: 1 [2]   Go Down
Author Topic: Compliling error when it all seems ok  (Read 1794 times)
0 Members and 1 Guest are viewing this topic.
Barcelona
Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
Indeed
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow, had to read that a few times to get around it smiley-lol Thanks for the explanation Tom Carpenter, just a couple things I don't get:

Quote
the vector table at the beginning to the hardware serial interrupt vector code
What are those??
Quote
By removing either of the Serial.print() calls, the length of the loop() function is reduced in size by just enough that the compiler can make the jump.
So a program could not compile because it's too long even though there is more than enough memory?
Quote
adding more code made the PCREL error go away as well
Without deleting the Serial.print()s?
Logged

Leeds, UK
Offline Offline
Edison Member
*
Karma: 71
Posts: 1641
Once the magic blue smoke is released, it won't go back in!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
adding more code made the PCREL error go away as well
Without deleting the Serial.print()s?
Yeah, weird huh.



A vector table in this context is a series of lines of code stored at specific memory addresses at the beginning of the program that instruct the AVR what part code to execute in the event of an interrupt occuring.
 This is the one from your code (you don't have to read through it, I'm just posting it as an example):
Code:
00000000 <__vectors>:
       0: 04 c1       rjmp .+520     ; 0x20a <__dtors_end>
       2: 00 00       nop

       4: 2f c1       rjmp .+606     ; 0x264 <__bad_interrupt>
       6: 00 00       nop

       8: 2d c1       rjmp .+602     ; 0x264 <__bad_interrupt>
       a: 00 00       nop

       c: 2b c1       rjmp .+598     ; 0x264 <__bad_interrupt>
       e: 00 00       nop

      10: 29 c1       rjmp .+594     ; 0x264 <__bad_interrupt>
      12: 00 00       nop

      14: 27 c1       rjmp .+590     ; 0x264 <__bad_interrupt>
      16: 00 00       nop

      18: 25 c1       rjmp .+586     ; 0x264 <__bad_interrupt>
      1a: 00 00       nop

      1c: 23 c1       rjmp .+582     ; 0x264 <__bad_interrupt>
      1e: 00 00       nop

      20: 21 c1       rjmp .+578     ; 0x264 <__bad_interrupt>
      22: 00 00       nop

      24: 1f c1       rjmp .+574     ; 0x264 <__bad_interrupt>
      26: 00 00       nop

      28: 1d c1       rjmp .+570     ; 0x264 <__bad_interrupt>
      2a: 00 00       nop

      2c: 1b c1       rjmp .+566     ; 0x264 <__bad_interrupt>
      2e: 00 00       nop

      30: 19 c1       rjmp .+562     ; 0x264 <__bad_interrupt>
      32: 00 00       nop

      34: 17 c1       rjmp .+558     ; 0x264 <__bad_interrupt>
      36: 00 00       nop

      38: 15 c1       rjmp .+554     ; 0x264 <__bad_interrupt>
      3a: 00 00       nop

      3c: 13 c1       rjmp .+550     ; 0x264 <__bad_interrupt>
      3e: 00 00       nop

      40: 11 c1       rjmp .+546     ; 0x264 <__bad_interrupt>
      42: 00 00       nop

      44: 0f c1       rjmp .+542     ; 0x264 <__bad_interrupt>
      46: 00 00       nop

      48: 0d c1       rjmp .+538     ; 0x264 <__bad_interrupt>
      4a: 00 00       nop

      4c: 0b c1       rjmp .+534     ; 0x264 <__bad_interrupt>
      4e: 00 00       nop

      50: 09 c1       rjmp .+530     ; 0x264 <__bad_interrupt>
      52: 00 00       nop

      54: 07 c1       rjmp .+526     ; 0x264 <__bad_interrupt>
      56: 00 00       nop

      58: 05 c1       rjmp .+522     ; 0x264 <__bad_interrupt>
      5a: 00 00       nop

      5c: 0c 94 f2 0d jmp 0x1be4 ; 0x1be4 <__vector_23>

      60: 01 c1       rjmp .+514     ; 0x264 <__bad_interrupt>
      62: 00 00       nop

      64: 1f c7       rjmp .+3646   ; 0xea4 <__vector_25>
      66: 00 00       nop

      68: 0c 94 96 08 jmp 0x112c ; 0x112c <__vector_26>

      6c: fb c0       rjmp .+502     ; 0x264 <__bad_interrupt>
      6e: 00 00       nop

      70: f9 c0       rjmp .+498     ; 0x264 <__bad_interrupt>
      72: 00 00       nop

      74: f7 c0       rjmp .+494     ; 0x264 <__bad_interrupt>
      76: 00 00       nop

      78: f5 c0       rjmp .+490     ; 0x264 <__bad_interrupt>
      7a: 00 00       nop

      7c: f3 c0       rjmp .+486     ; 0x264 <__bad_interrupt>
      7e: 00 00       nop

      80: f1 c0       rjmp .+482     ; 0x264 <__bad_interrupt>
      82: 00 00       nop

      84: ef c0       rjmp .+478     ; 0x264 <__bad_interrupt>
      86: 00 00       nop

      88: ed c0       rjmp .+474     ; 0x264 <__bad_interrupt>
      8a: 00 00       nop

      8c: eb c0       rjmp .+470     ; 0x264 <__bad_interrupt>
      8e: 00 00       nop

      90: 49 c7       rjmp .+3730   ; 0xf24 <__vector_36>
      92: 00 00       nop

      94: 0c 94 d5 08 jmp 0x11aa ; 0x11aa <__vector_37>

      98: e5 c0       rjmp .+458     ; 0x264 <__bad_interrupt>
      9a: 00 00       nop

      9c: e3 c0       rjmp .+454     ; 0x264 <__bad_interrupt>
      9e: 00 00       nop

      a0: e1 c0       rjmp .+450     ; 0x264 <__bad_interrupt>
      a2: 00 00       nop

      a4: df c0       rjmp .+446     ; 0x264 <__bad_interrupt>
      a6: 00 00       nop

      a8: dd c0       rjmp .+442     ; 0x264 <__bad_interrupt>
      aa: 00 00       nop

      ac: db c0       rjmp .+438     ; 0x264 <__bad_interrupt>
      ae: 00 00       nop

      b0: d9 c0       rjmp .+434     ; 0x264 <__bad_interrupt>
      b2: 00 00       nop

      b4: d7 c0       rjmp .+430     ; 0x264 <__bad_interrupt>
      b6: 00 00       nop

      b8: d5 c0       rjmp .+426     ; 0x264 <__bad_interrupt>
      ba: 00 00       nop

      bc: d3 c0       rjmp .+422     ; 0x264 <__bad_interrupt>
      be: 00 00       nop

      c0: d1 c0       rjmp .+418     ; 0x264 <__bad_interrupt>
      c2: 00 00       nop

      c4: cf c0       rjmp .+414     ; 0x264 <__bad_interrupt>
      c6: 00 00       nop

      c8: cd c0       rjmp .+410     ; 0x264 <__bad_interrupt>
      ca: 00 00       nop

      cc: 6b c7       rjmp .+3798   ; 0xfa4 <__vector_51>
      ce: 00 00       nop

      d0: 0c 94 14 09 jmp 0x1228 ; 0x1228 <__vector_52>

      d4: c7 c0       rjmp .+398     ; 0x264 <__bad_interrupt>
      d6: 00 00       nop

      d8: a5 c7       rjmp .+3914   ; 0x1024 <__vector_54>
      da: 00 00       nop

      dc: 0c 94 53 09 jmp 0x12a6 ; 0x12a6 <__vector_55>

      e0: c1 c0       rjmp .+386     ; 0x264 <__bad_interrupt>
      e2: 00 00       nop


... Other code in here ...


00000264 <__bad_interrupt>:
     264: cd ce       rjmp .-614     ; 0x0 <__vectors>

There is one line for each of the ATMega2560's 56 interrupt sources. Each one is made up of exactly 4 bytes (2 words), which are usually either a single JMP instruction (4bytes long) or an RJMP (2 bytes, with a NOP to make it up to 4). Those which are labelled __bad_interrupt are ones which your code hasn't implemented, which means that if for some reason the processor arrives there an error must have occurred. To handle the error it jumps to a function called __bad_interrupt, which in the case of your program does the standard thing which is to the restart the program from the beginning.

Here is the one the error mentioned, __vector_26
Code:
     68: 0c 94 96 08 jmp 0x112c ; 0x112c <__vector_26>
Notice how it neets to jump from the current line (0x0068 written on the left) to the location where the interrupt code is stored (0x112c). A JMP statement specifies an exact program memory location to move to, but it can only reference up to a 16bit address. What happens if the code is at address 0x10000? or higher? It can't get there. An Atmega has 256k of flash, but the instruction can only address 64k, so the compiler has to be careful where it places code.

You may think it is daft not being able to address all the flash, but there is actually an instruction which can. The atmega2560 has an instruction called EIJMP which is capable of addressing all of the program memory, in fact it can address up to 4MB of flash. However, it is not possible to use that instruction in the vector table as it takes 10 bytes of program memory to use it, but there is only space for 4bytes in the vector table.
Just for fun, this is how it would have to use EIJMP to get to address 0x10000. Each instructions used is 2 bytes long, and there are 5 in total which makes 10bytes.
Code:
ldi r16,0x01 ; Set up EIND and Z-pointer
out EIND,r16
ldi r30,0x00
ldi r31,0x00
eijmp ; Jump to 0x010000

Something about your code must have made the compiler for whatever reason put the interrupt code at an address >0xFFFF
« Last Edit: January 02, 2013, 03:30:04 pm by Tom Carpenter » Logged

~Tom~

Barcelona
Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
Indeed
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks a lot for your time and super explanation, I really appreciate it!!
Quote
Something about your code must have made the compiler for whatever reason put the interrupt code at an address >0xFFFF
So probably my not defined returns, right. I mean, could a perfectly debugged code not compile because casually the length between two vectors is two big?
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A good explanation, which also explains why the code compiled OK for me with a Uno as target - the Uno has only 32K of flash, so a JMP instruction can reach the entire address space.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Pages: 1 [2]   Go Up
Jump to: