Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
ksvitale
PostPosted: Feb 03, 2012 - 10:06 PM
Rookie


Joined: Jun 24, 2006
Posts: 32
Location: Central Florida, united States of America

Hello all:
I have searched the forum for this to no avail. If someone knows, point me in the right direction.

I have legacy ASM code for Mega32U4 that I need to implement minimal USB support in. I figure that since gcc pumps out object modules and the linker fills in the addresses then I can use them if I know the entry points to the routines and I can import the HEX file contents into my ASM program.

I have chosen the USB library from the Arduino dev folks and have written a null main just to get it to compile.

I have mapped the GCC registers for each routine (only about 10). GCC wants to place data before code so with some hacking of the Makefile, I have the code placed at 0x3100 (word-wise) and data right after it (just below the bootloader at 0x3800). I have reserved 12 bytes for the USB routines at the start of RAM, the rest is for my ASM routines. I have the linker emitting only the routine entry points from the symbolic table, which I use 'sed' and 'echo' to create an "include" file (with ".equ") for the assembler. This is all working fine and I am able to load the registers and properly call the routines.

Since I don't need the interrupt vector table that gcc creates, I want to disable the generation of it and save the ROM space.

Does anyone have any idea how to do that?

Thanks in advance.

Peace,
Scott

P.S. If anyone wants an info file posted on how to make a hybrid ASM project with C library support, I would be willing to do so.
 
 View user's profile Send private message  
Reply with quote Back to top
js
PostPosted: Feb 03, 2012 - 10:22 PM
10k+ Postman


Joined: Mar 28, 2001
Posts: 20383
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)

Not too sure but you may want to add -nostartfiles to the linker options.

_________________
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ksvitale
PostPosted: Feb 03, 2012 - 10:46 PM
Rookie


Joined: Jun 24, 2006
Posts: 32
Location: Central Florida, united States of America

Geez!!

Been searching for this off and on for a day or so to no avail .... then I find some hits to come up with "-nostartfiles -nodefaultlibs" as linker options.

Yes, JS, "-nostartfiles" was it!

Thanks!

Peace,
Scott
 
 View user's profile Send private message  
Reply with quote Back to top
js
PostPosted: Feb 03, 2012 - 10:56 PM
10k+ Postman


Joined: Mar 28, 2001
Posts: 20383
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)

Just a lucky guess Smile ....actually I looked up the options in one of the booloader programs where the vectors needed not be there (smiley's bootloader tutorial).

_________________
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Feb 04, 2012 - 12:14 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England

Note that if you use -nostartfiles it then becomes your responsibility to do what the CRT was previously doing. So if you use .data or .bss variables you have to set those up yourself.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
westfw
PostPosted: Feb 05, 2012 - 01:50 AM
Resident


Joined: Jun 19, 2002
Posts: 957
Location: SF Bay area

Quote:
if you use .data or .bss variables you have to set those up yourself.

also, setting the "known zero" register (r1) to zero. Which apparently happens on some chips during power up and/or HW reset, but not all the time. As the Arduino team discovered the hard way!
http://www.arduino.cc/cgi-bin/yabb2/YaB ... 9218/39#39
http://code.google.com/p/optiboot/issues/detail?id=26
http://code.google.com/p/optiboot/issues/detail?id=40
 
 View user's profile Send private message  
Reply with quote Back to top
ksvitale
PostPosted: Feb 05, 2012 - 02:42 AM
Rookie


Joined: Jun 24, 2006
Posts: 32
Location: Central Florida, united States of America

Hi all:
Thanks for the input.

I modified the original C-code and added in-line assembler directive "clr r1" to zero the r1 registers in the routines that used it in the resulting assembly listing.

I am explicitly executing push/pop before/after calling the routines ... that is after I looked over the resulting ASM listing to see which registers are being used.

As it turns out, to support single-character xmit/recv in Virtual Com (CDC) mode, only a few routines are needed so the "transmit a buffer" and "CDC control signals" routines are not needed. This cuts out nearly 1K of program space for a total memory footprint size of 1.5K bytes.

In the header file for the C-code, I am using the following macro def:

Code:

#undef PROGDATA
#define PROGDATA __attribute__ ((section (".progdata")))


Then for all the PROGMEM "data", I use something like:

Code:

const struct usb_string_descriptor_struct PROGDATA string1 = {
   sizeof(STR_MANUFACTURER),
   3,
   STR_MANUFACTURER
};


I am not an "expert" at Makefiles, actually, not even "fluent" but I was able to modify the Makefile and do the following:

Code:

PROG_START = 0x6800     #PROGMEM code
PROGDATA_START = 0x6E00 #PROGMEM data

DATA_START = 0x800A80 #RAM variables


then passed the linker the following:

Code:

CDEFS += -DPROG_START_ADDR=$(PROG_START)UL

LDFLAGS += -Wl,--retain-symbols-file $(TARGET)-api.lst
LDFLAGS += -Wl,--no-gc-sections
LDFLAGS += -Wl,--section-start=.text=$(PROG_START) -nostartfiles -nodefaultlibs
LDFLAGS += -Wl,--section-start=.progdata=$(PROGDATA_START)

LDFLAGS += -Wl,--section-start=.data=$(DATA_START)


The contents of "$(TARGET)-api.lst" is just the names of each function I want access to, the interrupt vectors I want and the starting location of the code block, like so:

Code:

__ctors_start
usb_serial_init
usb_serial_configured
usb_serial_shutdown
usb_serial_getchar
usb_serial_available
usb_serial_flush_input
usb_serial_putchar
usb_serial_putchar_nowait
usb_serial_flush_output
__vector_10
__vector_11


I then parse the symbols and create a HEX file that I drop into my ASM "include directory" with this section in the Makefile. The "--gap-fill 0xFF" directive insures that the space between code and data in FLASH is filled with 0xFF so srec_cat doesn't complain and toss "ORG" statements into your ASM's include file.

Code:

# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
   @echo
   @echo $(MSG_FLASH) $@
   $(OBJCOPY) -O $(FORMAT) --gap-fill 0xFF -R .eeprom -R .fuse -R .lock $< $@

# Create the include hex listing and subroutine pointers for use with the project.
%.inc:
   @echo $(MSG_CREATING_INCLUDE) $< $@ at $(PROG_START)
   @$(SREC) $(TARGET).hex -intel -offset -$(PROG_START) -o - -asm -HEXadecimal_STyle | \
      $(SED) 's/ DB / .db/g' > $(INC_DIR)/Code_$(TARGET).inc
   @$(CAT) $(TARGET).sym | $(SED) 's/ T / .equ /g' | \
      $(SED) 's/0000/0x/g' | \
      $(SED) 's/__vector_10/USB_GEN_int/g' | \
      $(SED) 's/__vector_11/USB_COM_int/g' > temp.sym
   @$(REMOVE) $(INC_DIR)/Defs_USBserial.inc
   @$(CAT) temp.sym | while read ADDR SYMBOL ; do \
      echo "$$SYMBOL = $$ADDR/2" >> $(INC_DIR)/Defs_USBserial.inc ; \
      done
   @$(REMOVE) temp.sym


GCC uses byte addresses whereas AVR ASM uses word addresses so I create an ".equ" value that is the "address / 2". I tried using the "bc" calculator to calculate the addresses on the fly before stuffing them in a definition file but I could not get that to work (at all). The resulting include file looks like this:

Code:

.equ __ctors_start = 0x6800/2
.equ usb_serial_init = 0x6806/2
.equ usb_serial_shutdown = 0x683a/2
.equ usb_serial_configured = 0x6856/2
.equ usb_serial_getchar = 0x685c/2
.equ usb_serial_available = 0x68a6/2
.equ usb_serial_flush_input = 0x68dc/2
.equ usb_serial_putchar = 0x6902/2
.equ usb_serial_putchar_nowait = 0x6988/2
.equ usb_serial_flush_output = 0x69ca/2
.equ USB_GEN_int = 0x69ec/2
.equ USB_COM_int = 0x6a62/2


I stick the follwoing at the bottom of the main ASM file so the library routines go in after my project's main code (the ".cseg" and ".org" insure that!):

Code:

;******************************************************************************
;USB Support
;******************************************************************************
#if ( defined(__ATmega32U4__) && (USB) )
.cseg
.org  __ctors_start  ;start of ROM code + data
.include "Include/Code_usb_serial.inc"
#endif


I have not yet figured out how to pull the addresses of the RAM-based variables from the symbol table, so I have added this in another include file:
Code:

#if ( defined(__ATmega32U4__) && (USB) )
.equ   USB_SERIAL_RAM   = 0x0A80   ;start of RAM variables
;
#if ( (FCLK != 8000000) && (FCLK != 16000000) )
   #error "USB support is enabled, 8MHz or 16MHz clock only!"
#endif
#endif


and this in my "data defs" include file:

Code:
;=============================================================================
; USB Serial I/O support
;=============================================================================
#if ( defined(__ATmega32U4__) && (USB) )
USBtxBufr:   .byte   64         ;TX buffer for USB
;
.org      USB_SERIAL_RAM      ;start of USB serial I/O RAM usage
cdc_line_coding:         .byte   8
usb_configuration:         .byte   1
cdc_line_rtsdtr:         .byte   1
transmit_flush_timer:      .byte   1
transmit_previous_timeout:   .byte   1
usb_suspended:            .byte   1
#endif


That pretty much covers it.

Hope that helps others.

Peace,
Scott
 
 View user's profile Send private message  
Reply with quote Back to top
bobgardner
PostPosted: Feb 05, 2012 - 10:05 PM
10k+ Postman


Joined: Sep 04, 2002
Posts: 21271
Location: Orlando Florida

Nice to know there is another avr programmer in Central Florida.

_________________
Imagecraft compiler user
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits