Atmega168 vs Atmega168A compilation/execution

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello wonderful wealth of information forum which has helped me so much, I have a question about an Atmega to ask.

Background:
Wrote a big code and burned it onto an atmega88. Used up 7kB of the flash so decided to upgrade to the Atmega168 to get those 16kB. I bought a DIP version of the Atmega168 called the Atmega168A-20PU. Using AVR Studios 4, I changed in the config to Atmega168A, compiled the old code, ID verified the device using STK500, and burned the program into the micro. The code executed until it hit the "sei();" line then it began outputting a messed up UART message. I looked through my code a thousand times and couldn't figure out why it didn't work when I executed the "sei();"

Even though the chip says Atmega168A on the DIP version, I changed the configuration to regular old Atmega168 just experimenting, recompiled and reburned. The program then executed perfectly enough (although I have found other bugginess in the code that wasn't there when the program is burned into an Atmega88).

Question:
Why do I have to tell AVR Studio 4 that an Atmega168A is an Atmega168 to get the interrupts to somewhat work correctly???

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think it is an issue between the 168 and 168A, but going from the 88 to the 168.

The biggest difference between the ATmeaga48/88 and the 168/328 is the addition of JMP and CALL instructions to navigate flash memory above 8K. The interrupt jump table vectors for the 48 & 88 accepts only the RJMP instruction (single word) while the 168, 328 expects the JMP instruction (double word).

Stan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
328 expects the JMP instruction (double word).
It doesn't "expect" anything. The chip itself doesn't care what you put there. It does have room for a JMP without clobbering another vector, but RJMP works just fine as well.

As far as the difference between a mega168 and a mega168A, there is none. The only difference is the die process (and some electrical differences as a result). Functionally they are identical. It is possible that there is a problem in the compiler, but I doubt it.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The interrupt jump table vectors

Perhaps the C compiler (or avr-libc) version you have installed has an incorrect definition (internally) for the size of the interrupt vectors on the 168A. It would be a simple matter of an incorrect crt168a.o, I think.
My impression is that sometimes the "new chips added to old compiler versions" operation is sometimes done a bit hastily...
(For example the megaxx8P processors are essentially identical to the megaxx8 processors, but in gcc4.3.2 it looks like their ioXXXp.h files were implemented in the "new" way instead of being consistent with the non-P chips. So upgrading your Arduino from m168 to m328p means that suddenly all the "PB1" pin definitions disappear (in favor of "PORTB1"))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know about older toolchains, but in the latest AS6 all 8-bit AVRs have Pxn defined as well as PORTxn. This is guaranteed by avr/portpins.h, which is included automatically by avr/io.h.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

He did say he was using AVRS 4.
That means his gcc version is close to "random", right?

FWIW, I believe that modern versions of avr-gcc use some magical tool to generate the ioxxxx.h files from some xml device specification direct from Atmel, and that the problems I reported for 4.3.2 were probably due to using that tool to add the P cpus while the non-P cpus were still using modular hand-edited .h files (48, 88, 168, all included iomx8.h) Or something like that. But it was just an example of the sort of randomness that can creep into a "release" pretty easily.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess I can actually confirm my theory. Using winavr-20100110, in lib/avr5/crtm168*.o, if I look at crtm168.o, I see:

C:\WinAVR-20100110\avr\lib\avr5>avr-objdump -S crtm168.o

crtm168.o:     file format elf32-avr

Disassembly of section .text:

00000000 <__bad_interrupt>:
   0:   0c 94 00 00     jmp     0       ; 0x0 <__bad_interrup

Disassembly of section .vectors:

00000000 <__vectors>:
   0:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
   4:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
   8:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
   c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  10:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  14:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  18:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  1c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  20:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  24:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  28:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  2c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  30:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  34:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  38:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  3c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  40:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  44:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  48:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  4c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  50:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  54:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  58:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  5c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  60:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  64:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>

Disassembly of section .init2:

And if I look at crt168a.o, I see that it's missing a good number of the vectors:

C:\WinAVR-20100110\avr\lib\avr5>avr-objdump -S crtm168a.o

crtm168a.o:     file format elf32-avr

Disassembly of section .text:

00000000 <__bad_interrupt>:
   0:   0c 94 00 00     jmp     0       ; 0x0 <__bad_interrupt>

Disassembly of section .vectors:

00000000 <__vectors>:
   0:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
   4:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
   8:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
   c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  10:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  14:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  18:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  1c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  20:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  24:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  28:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  2c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>
  30:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>

Disassembly of section .init2:

So there are only 13 vectors defined for the m168a for some reason. (half of the 26 it should have, but it has correct 4-byte jump instructions, so perhaps it's size limited assuming short vectors, even though it has generate long vector jumps?) Since the UART starts at Vector19, it's not surprising that it fails.

If you want the atmega168a device type to work, you can probably just copy the crtm168.o over the crt168a.o file.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like avr-libc issue #29964.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thank you for the responses

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do I replace the object file? A workaround method would be appreciated besides selecting the wrong chip in the configuration, thanks again

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The simplest workaround is to just say you are using ATmega168. Compilation and programming will work fine even though it actually a A version of chip.

One day, Atmel will resolve the header file and build anomalies. When that day comes, you can choose 'ATmega168A'.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It may already be fixed in AS6, I doubt that AS4/winAvr will ever get an update with a fix. :(

Which version of AS4 are you using? If 4.19 maybe you can use Atmel's toolchain instead of winAvr, maybe it has been fixed there.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can't you -nostartfiles and link with crtm168.o?

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
It may already be fixed in AS6

crtm168a.o looks correct in AS6...

Quote:
Looks like avr-libc issue #29964.

I don't think so. For one thing, wasn't that report rejected? It may have gone away before anyone noticed, when Atmel and/or the avr-libc people started consistently computer-generating the .h and crt*.o; my guess was that this was a carelessness adding new cpus to old versions, where some lib files were generated one way, and others another way. (do you happen to know when that happened? It would have been a major "feature", right? I tried searching the avr-libc issue database, but I don't think I like its search engine...)

The fix for winavr would be something like:
Start a "command prompt"
connect to your winavr install directory

Quote:
C:\WinAVR-20100110>cd \WinAVR-20100110

Connect to the directory contain the suspect library. (here "avr5" refers to a specific sub-architecture of avr. has this instruction but not that one, etc.)
Quote:
C:\WinAVR-20100110>cd avr\lib\avr5

Check for the broken file. Note that the library file for 168a is shorter than for 168; it shouldn't be!

Quote:
C:\WinAVR-20100110\avr\lib\avr5>dir crtm168?.o
Volume in drive C has no label.
Volume Serial Number is F8E4-41D7

Directory of C:\WinAVR-20100110\avr\lib\avr5

01/06/2010 11:13 AM 2,276 crtm168.o
01/06/2010 11:13 AM 1,704 crtm168a.o
01/06/2010 11:13 AM 2,276 crtm168p.o


Save a copy of the bad file
Quote:
C:\WinAVR-20100110\avr\lib\avr5>rename crtm168a.o bad-crtm168a.o

Make a copy of a good file:

Quote:
C:\WinAVR-20100110\avr\lib\avr5>copy crtm168.o crtm168a.o

Check to make sure it worked (now the files are all the same length)
Quote:
C:\WinAVR-20100110\avr\lib\avr5>dir crtm168?.o
Volume in drive C has no label.
Volume Serial Number is F8E4-41D7

Directory of C:\WinAVR-20100110\avr\lib\avr5

01/06/2010 11:13 AM 2,276 crtm168.o
01/06/2010 11:13 AM 2,276 crtm168a.o
01/06/2010 11:13 AM 2,276 crtm168p.o
3 File(s) 6,828 bytes
0 Dir(s) 639,123,456 bytes free

(I should point out that this sort of off-the-cuff "This should work" procedure is probably VERY SIMILAR to what happened that caused the problem in the first place!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for all the help once again everyone, I'll implement a repair this weekend (I work with AVRs moonlighting on the weekends)