[TUT] Using USB enabled Xegas with non-compatible Winavr

Last post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Compiler support for the new USB enabled Xmegas is at this time only found in AVR Toolchain . There is assembler support for it in Winavr-20100110, if you use AS4.19 . But I've been able to trick Winavr and AS4.18 into compiling for an Xmega32A4U .

Two main parts are needed for this, the startup code must be adjusted and the correct *.h file must be used . Avr-GCC startup code is provided with a general file called gcrt1.S modified and assembled for specific MCUs ( named crt_whatever.o ) and a linker script for a given chip .

What the crt startup code does, in coordination with the script file :

1) Takes care of the IVT including the bad interrupt part .

2) The copy_data routine, when needed .

3) clear_bss routine, when needed .

4) The jump to main and exit code, if the app does return ( somehow ) .

Once the app gets to main, it's *.h file time and we're good to go after that .

The idea is to adjust the gcrt1.S for my Xmega, and use the *.h from the "TOOLCHAIN" in the io.h file instead of the one for Xmega32A4 ( so it would then also have to be used when working with an Xmega32A4 ) . Another option would be to use the regular *.h then add a 2nd *.h that has the "diff'ed" stuff from the USB header file . A compile-time constant would control if the 2nd *.h is needed or not .

Because of the design structure of the Xmegas within a given series, the script file for the Xmega32A4 can be used ( as best as I can tell ) and so the -T option won't have to be passed to the linker ! This Xmega has vectors defined up to #93 ( same as regular one ), then adds two more that are USB related, #125 & #126 . I moved the extra vectors in the *.S file to the top since they would show up in the *.lss file as annoying text . The asm file also has code for a copy_data routine, but I commented that out since the chip is < 64K and in that case libgcc.a will provide it ( clear_bss also ).

Steps, using my #1 & #2 sign. toolchain :

0) Lie like a politician and choose Xmega32A4 as pjt. MCU ( as least your lips won't be movin' ! ) .

1) Add my crtxm32A4U.S source file to your pjt. tree.

2) Add avrlibc's macros.inc, needed for the *.S .

3) Add -nostartfiles as a linker option, which will keep the crt file for Xmega32A4 from being added .

Boom, done ! Here's a short program that produces correct *.lss :

#include  
#include  
#include  
#include  


uint8_t   bet, winning = 90; 

int   main(void){

	ADCA_CTRLA = 0x12;
	while(1);
}

// vector #126
ISR( USB_TRNCOMPL_vect, ISR_NAKED ) {
	
	PORTA_DIRSET = 0xAD;
	reti();
}

// vector #125
ISR( USB_BUSEVENT_vect ) {

	CRC_CTRL = CRC_RESET_RESET1_gc;
}

I don't know how to strip out the text from the *.S that gets into the *.lss, but there must be an option . Adjusting the crt.S file should allow it to work with the other USB_Xmegas . From what little I know this "should" always work ... We'll see what the experts say about this .

Original gcrt1.S :

http://svn.savannah.nongnu.org/viewvc/trunk/avr-libc/crt1/gcrt1.S?root=avr-libc&view=markup

macros.inc :

http://jwtanner.com/rtos/macros.inc

Jerome

Edit : I found a bug ( just too good to be true ) ! It's not doing the copy_data and clear_bss routines correctly . The vars aren't being added in, though the routines run . Look in the *.lss and r16 should be compared to 0x02, but it's being compared to 0x00 . I KNOW I saw the build output showing bytes in the data region and it sim'ed fine ( last night ! ) !

Edit 2: Here are my compiler/linker options passed :

/* Compiler switches */

CFLAGS += -fno-inline-small-functions
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections 
CFLAGS += -mcall-prologues

/* Linker switches */

LDFLAGS += -Wl,--relax      
LDFLAGS += -Wl,--gc-sections

Last night I hadn't added ANY of the above yet . I just found that it doesn't like the linker switch

-Wl,--gc-sections

When I leave that one out, the routines behave . Again, it's all about the experts at this point .

Attachment(s): 

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

@Jerome

I got some hints from Jörg.

He writes

Quote:
If there are no more interrupt vectors that got added (or the
additional vectors are not needed right now), hacking the IO
header file might be enough, yes.

Quote:

Well, I never really liked those --gc-sections and stuff. For a
correctly written (non-C++) program, they are not needed.

Anyway, when using -nostartfiles, it must be ensure that the new
crt*.o file comes *very first* on the linker commandline, before
anything else.

Maybe this is helpfull.

/Bingo

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

Bingo600 wrote:
@Jerome

I got some hints from Jörg.

He writes

Quote:
If there are no more interrupt vectors that got added (or the
additional vectors are not needed right now), hacking the IO
header file might be enough, yes.

Quote:

Well, I never really liked those --gc-sections and stuff. For a
correctly written (non-C++) program, they are not needed.

Anyway, when using -nostartfiles, it must be ensure that the new
crt*.o file comes *very first* on the linker commandline, before
anything else.

Maybe this is helpful.

/Bingo

Bingo, I just replaced the original Xmega32A4 *.h file with the Xmega32a4U one . That should be ok for now . I'm using Studio 4.18 / Winavr-20100110 on XP, how do I guarantee that crt.o will be 1st ?

I'm surprised that Jorg said that since that linker switch keeps unreferenced functions from ending up in the final *.hex and so saving ALOT of bytes ( depending on what's in those pjt. files of course ) . I would guess the only other way to save would be to copy only needed functions into another new file for a given app ( and so wouldn't have to use the switch ) ?

For others reading this, the libgcc.a's startup code acts right when I actually use the vars in main(), compared to what I put in the code above and it's totally right when that linker switch is left out .

Thanks alot for the help !
Jerome

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Quote:

the libgcc.a's startup code

Sorry but what has libgcc.a got to do with startup code? The CRT comes from crt.o in AVR-LibC

 

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

clawson wrote:
Quote:

the libgcc.a's startup code

Sorry but what has libgcc.a got to do with startup code? The CRT comes from crt.o in AVR-LibC
Clawson, there's startup code in there, too . It's structured so that MCUs have < 64K of flash, it comes from that file and for > 64K the crtX.o file does it ( that's what I found others saying in my Google searching ) . I think it's still set up that way . I did a avr-objdump -S on the libgcc.a for the Xmega32a4 and I saw copy and clear_bss code in there .

I've also commented out the copy routine from my crtX.S, and clear_bss isn't even in my crtX.S but they both appear in the *.lss .

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
2) The copy_data routine, when needed.
3) clear_bss routine, when needed.
The startup-code is a blend from avr-libc and libgcc. To make it more confusing, the avr-libc part depends on the GCC version.

libgcc contributes:

A) __do_copy_data
B) __do_clear_bss
C) __do_global_ctors
D) __do_global_dtors

avrfreaks does not support Opera. Profile inactive.