Replacing Xmega128A1 default interrupt vector table in AS6

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

Is it possible to replace the default interrupt vector table code (assembly listing shown below) with my own code? I've tried telling the Linker to not use standard startup files and standard libraries, and creating my own code at __vectors, but that results in a dupicate symbol error.

It appears this code resides in .../AVRToolchain/avr/lib/avrxmega7/crtx128a1.o and the various loader scipts .../AVRToolchain/avr/lib/ldscripts/avrxmega7.* cause this code to be loaded into the application. Do I have to create my own crtx128a1.o and/or loader script? or can I tell AS6 to not use this code and instead use code included in a project/solution? I've looked through the Makefile AS6 generates and don't see any meaningful, not that I know anything about Makefiles...

Quote:

00000000 <__vectors>:
0: 3b c1 rjmp .+630 ; 0x278 <__ctors_end>
2: 00 00 nop
4: 5d c1 rjmp .+698 ; 0x2c0 <__bad_interrupt>
6: 00 00 nop
8: 5b c1 rjmp .+694 ; 0x2c0 <__bad_interrupt>
a: 00 00 nop
c: 59 c1 rjmp .+690 ; 0x2c0 <__bad_interrupt>

62: 00 00 nop
64: ab c2 rjmp .+1366 ; 0x5bc <__vector_25>
66: 00 00 nop
68: f3 c2 rjmp .+1510 ; 0x650 <__vector_26>
6a: 00 00 nop
6c: 29 c1 rjmp .+594 ; 0x2c0 <__bad_interrupt>
6e: 00 00 nop
70: 30 c3 rjmp .+1632 ; 0x6d2 <__vector_28>
72: 00 00 nop
74: 78 c3 rjmp .+1776 ; 0x766 <__vector_29>
76: 00 00 nop
78: 23 c1 rjmp .+582 ; 0x2c0 <__bad_interrupt>
7a: 00 00 nop
7c: 21 c1 rjmp .+578 ; 0x2c0 <__bad_interrupt>

00000278 <__ctors_end>:
278: 11 24 eor r1, r1
27a: 1f be out 0x3f, r1 ; 63
27c: cf ef ldi r28, 0xFF ; 255

Gamu The Killer Narwhal
Portland, OR, US
_________________
Atmel Studio 6.2
Windows 8.1 Pro
Xplained boards mostly

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

Quote:

I've tried telling the Linker to not use standard startup files and standard libraries, and creating my own code at __vectors, but that results in a dupicate symbol error.

Show us that. That should not have happened and either -nostartfiles or -nostandardlib should have worked for you. Remember that options to the linker, depending where/how the are placed/past may need a -Wl, at the start.

EDIT: this is really odd. If I build a simple program with WinAVR and an Mfile Makefile with LDFLAGS += -nostartfiles added I can easily get:

00000000 
: #include #include #include int main(void) { DDRB = 7; 0: 87 e0 ldi r24, 0x07 ; 7 2: 87 bb out 0x17, r24 ; 23 PORTB = 0xF3; 4: 83 ef ldi r24, 0xF3 ; 243 6: 88 bb out 0x18, r24 ; 24 8: ff cf rjmp .-2 ; 0x8 <__zero_reg__+0x7>

But whether I use a C or C++ project and whether I use -Wl,-nostartfiles or -Wl,-nostandardlib in AS6 I simply cannot get it to drop the vector table and CRT. It's like it is simply ignoring those linker options?!?

Looks like this may be an AS6 toolchain bug.

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

Quote:
But whether I use a C or C++ project and whether I use -Wl,-nostartfiles or -Wl,-nostandardlib in AS6 I simply cannot get it to drop the vector table and CRT. It's like it is simply ignoring those linker options?!?

Looks like this may be an AS6 toolchain bug.

It appears you have already "show[n] us that." So it appears it is easy to do what I want and, if AS6 wasn't broken, what I tried would have worked. I have WinAVR installed and have been looking for some motivation to learn how to use make. I seem to have found it.

Thanks for looking into this!

Gamu The Killer Narwhal
Portland, OR, US
_________________
Atmel Studio 6.2
Windows 8.1 Pro
Xplained boards mostly

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

It appears WinAVR is doing the same thing. I checked with the GCC manual and found this:

Quote:
-nostartfiles: Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used.

-nodefaultlibs: Do not use the standard system libraries when linking. Only the libraries you specify will be passed to the linker. The standard startup files are used normally, unless -nostartfiles is used. The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.

-nostdlib: Do not use the standard system startup files or libraries when linking. No startup files and only the libraries you specify will be passed to the linker. The compiler may generate calls to memcmp, memset, memcpy and memmove.

These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.

One of the standard libraries bypassed by -nostdlib and -nodefaultlibs is libgcc.a, a library of internal subroutines that GCC uses to overcome shortcomings of particular machines, or special needs for some languages. (See Interfacing to GCC Output (GNU Compiler Collection (GCC) Internals), for more discussion of libgcc.a.) In most cases, you need libgcc.a even when you want to avoid other standard libraries. In other words, when you specify -nostdlib or -nodefaultlibs you should usually specify -lgcc as well. This ensures that you have no unresolved references to internal GCC library subroutines. (For example, __main, used to ensure C++ constructors will be called; see collect2 (GNU Compiler Collection (GCC) Internals).)


So I added declarations for the four mem* function specidifed. I then modifed the Makefile AS6 generated, copied the project into a tmp dir, and tried building with WinAVR. Here are the last few lines of the build:
Quote:
vector_table.o: In function `__vectors':
C:\tmp/vector_table.s:8: multiple definition of `__vectors'
c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avrxmega7/crtx128a1.o:(.vectors+0x0): first defined here
c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions
make: *** [XA1X_Common_ISR.elf] Error 1

And the map file contains:
Quote:
Archive member included because of file (symbol)

c:/winavr/bin/../lib/gcc/avr/4.3.3/avrxmega7\libgcc.a(_exit.o)
c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avrxmega7/crtx128a1.o (exit)

Linker script and memory map

LOAD c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avrxmega7/crtx128a1.o
LOAD main.o
LOAD vector_table.o
START GROUP
LOAD c:/winavr/bin/../lib/gcc/avr/4.3.3/avrxmega7\libgcc.a
END GROUP
Address of section .BOOT set to 0x20000
LOAD c:/winavr/bin/../lib/gcc/avr/4.3.3/avrxmega7\libgcc.a
LOAD c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avrxmega7\libc.a
LOAD c:/winavr/bin/../lib/gcc/avr/4.3.3/avrxmega7\libgcc.a


Archive member included because of file (symbol) is indicating _exit.o is causing the CRT to be loaded. The exit code is technically not a "startup" file, but I specified all three of -nostartfiles, -nodefaultlibs and -nostdlib, so no libraries should be included except for libgcc, yet crtx128a1.o and libc.a are being loaded. I don't get it...

If it helps, the attached ZIP contains the following:

    "makedep.mk" and "Makefile.AS6" as generated by AS6.

    "Makefile" is a modified version of "Makefile.AS6" with paths changed to the WinAVR install dir (C:\WinAVR) and some extraneous stuff removed.

    "make.txt" is the captured output of a make clean all.

    "...MAP" is the map file generated from the build before it dies.

Attachment(s): 

Gamu The Killer Narwhal
Portland, OR, US
_________________
Atmel Studio 6.2
Windows 8.1 Pro
Xplained boards mostly

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

After more investigating...

AS6 avr-ld.exe: GNU ld (AVR_8_bit_GNU_Toolchain_3.4.0_663) 2.22
WinAVR avr-ld.exe: GNU ld (WinAVR 20100110) 2.19

Of the three options -nostartfiles, nodefaultlibs and -nostdlib, only -nostdlib is indicated as a valid option via avr-ld.exe --help (for either version). And when -Wl,-nostdlib is included on the avr-gcc.exe command line, the command silently aborts, as evidenced by the lack of an output file (*.elf).

Output from make clean all with -Wl,-nostdlib:

Quote:
C:\WinAVR\bin\avr-gcc.exe -o XA1X_Common_ISR.elf main.o vector_table.o -Wl,-Map=XA1X_Common_ISR.map -mmcu=atxmega128a1 -Wl,--allow-multiple-definition -Wl,-nostdlibs
Finished building target: XA1X_Common_ISR.elf
C:\WinAVR\bin\avr-objcopy.exe -O ihex -R .eeprom -R .fuse -R .lock -R .signature
XA1X_Common_ISR.elf XA1X_Common_ISR.hex
C:\WinAVR\bin\avr-objcopy.exe: 'XA1X_Common_ISR.elf': No such file
make: *** [XA1X_Common_ISR.elf] Error 1

and without it:

Quote:
Building target: XA1X_Common_ISR.elf
C:\WinAVR\bin\avr-gcc.exe -o XA1X_Common_ISR.elf main.o vector_table.o -Wl,-Map=XA1X_Common_ISR.map -mmcu=atxmega128a1 -Wl,--allow-multiple-definition
Finished building target: XA1X_Common_ISR.elf
C:\WinAVR\bin\avr-objcopy.exe -O ihex -R .eeprom -R .fuse -R .lock -R .signature XA1X_Common_ISR.elf XA1X_Common_ISR.hex
C:\WinAVR\bin\avr-objcopy.exe -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex XA1X_Common_ISR.elf XA1X_Common_ISR.eep || exit
C:\WinAVR\bin\avr-objdump.exe -I elf32-avr -d XA1X_Common_ISR.elf > XA1X_Common_ISR.lss
C:\WinAVR\bin\avr-size.exe XA1X_Common_ISR.elf
text data bss dec hex filename
1178 0 0 1178 49a XA1X_Common_ISR.elf

ZIP archive contains build dir after a successful build (without -Wl,-nostdlib and with -Wl,--allow-multiple-definition to prevent duplicate symbol errors) with an updated Makefile.

Attachment(s): 

Gamu The Killer Narwhal
Portland, OR, US
_________________
Atmel Studio 6.2
Windows 8.1 Pro
Xplained boards mostly