Cannot make ext-coff with binutils 060523

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

I'm not sure if this should go here or under the general AVR forum. Sorry if I got it wrong.

I'm having problems generating COFF using the binutils version 060523 from the AtmanAVR's GCC4.1-WINAVR distro. The problem is given below. Note that I must use COFF as my code size is significantly larger than 64K and the DWARF-2 format still doesn't support code of that size.

Converting to AVR Extended COFF: MainProcessorBoard.cof
C:/WinAVR/bin/avr-objcopy --debugging --change-section-address .data-0x800000 --change-section-address .bss-0x800000 --change-section-address .noinit-0x800000 --change-section-address .eeprom-0x810000 -v -O coff-ext-avr MainProcessorBoard.elf MainProcessorBoard.cof

copy from `MainProcessorBoard.elf' [elf32-avr] to `MainProcessorBoard.cof' [coff-ext-avr]
int constant type not supported in coff-ext-avr
make: *** [extcoff] Error 1

Any clues what this is telling me? How would I avoid using constant ints, as they show up regularly in the constants stored in program flash?

I'm almost there with the latest compiler and avrlib! The compiled code works, just need to be able to reliably debug it!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Ist this C++? Most C++ features that are not part of K&R C
(yes, the very old pre-C89 version) cannot be supported by COFF.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Nope, it is not C++. Straight C.

Here's the C stuff from the make file (this is edited to remove the kruft):

MCU = atmega2560

# Compiler flag to set the C Standard level.
#     c89   = "ANSI" C
#     gnu89 = c89 plus GCC extensions
#     c99   = ISO C99 standard (not yet fully implemented)
#     gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99


# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL -DGCC_MEGA_AVR -D__AVR_ATmega2560__ $(DBGDEFINE)

#---------------- Compiler Options C ----------------
#  -g*:          generate debugging information
#  -O*:          optimization level
#  -f...:        tuning, see GCC manual and avr-libc documentation
#  -Wall...:     warning level
#  -Wa,...:      tell GCC to pass this to the assembler.
#    -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
CFLAGS += -Wundef
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)

# Compiler flags to generate dependency files.
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d

# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) -O$(OPT) $(GENDEPFLAGS)

# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
	@echo
	@echo $(MSG_COMPILING) $<
	$(CC) -c $(ALL_CFLAGS) $(PROJ)/$< -o $@ 

# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
	@echo
	@echo $(MSG_LINKING) $@
	$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)

Maybe I have an improper compiler flag set? The set looks reasonable, but I must admit I haven't gone through the gcc options to be sure.

Thanks for looking!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Whoops! Forgot to add:

# Debugging format.
#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
#     AVR Studio 4.10 requires dwarf-2.
#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = stabs
#DEBUG = dwarf-2

CC = $(WINAVR)/bin/avr-gcc
OBJCOPY = $(WINAVR)/bin/avr-objcopy
OBJDUMP = $(WINAVR)/bin/avr-objdump

# Change the build target to build a HEX file or a library.
build: elf hex lss sym extcoff

# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000

extcoff: $(TARGET).elf
	@echo
	@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
	$(COFFCONVERT) -v -O coff-ext-avr $< $(TARGET).cof

All of this used to work with 3.4.5, of course with the mcu set to 1280 instead of 2560.

Thanks!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Can you provide a minimal example that reproduces this?

What does the output from "avr-objdump -g yourfile.elf" say?
Can you spot the word "const" anywhere there?

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Ahh! Found it! It was code in the memory manager I had imported.

At the top level, there is a declaration:

static unsigned int  heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );

where portBYTE_ALIGNMENT is a #defined value. This created the following from avr-objdump:

void *pvPortMalloc (register size_t xWantedSize /* 0x1c */)
{ /* 0x8018 */
  const int heapSTRUCT_SIZE = 4;
  { /* 0x8018 */
    register void *pvReturn /* 0x10 */;
    register xBlockLink *pxNewBlockLink /* 0x1a */;

If I change the variable declaration to a #define (which, in this case is really how it's used):

#define heapSTRUCT_SIZE ( sizeof( xBlockLink ) + ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) )

Then everything works fine.

Thank you very much for the pointer to avr-objdump! It is now part of my makefile so I am able to use it in the future.

If you would like the code (heap_2.c from FreeRTOS) as an example, I would be happy to provide it. Just let me know.

Thanks again, Joerg!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

I've never seen that happen in C before, but that's probably because
one usually doesn't declare a const int object in C (makes no sense,
will allocate memory anyway, unlike in Pascal or C++).

OK, glad you found it.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

In retrospect, the way I read the output of objdump -g, it appears
that GCC 4.x now treats a static const object really as a constant,
rather than a variable that is not going to be changed. That perhaps
explains why the same code did pass the COFF conversion with GCC 3.x.

I wasn't even aware the C standard does allow for this.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Kewl! I helped you learn something!

If I understand the situation correctly, my solution (turning the static const into a #define) will be a waorkaround for practically all cases of this type.

The only other static const "variables" I have are stored in program flash and so not affected by the COFF conversion.

Thanks again for your help, Jörg!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

> If I understand the situation correctly, my solution (turning the
> static const into a #define) will be a waorkaround for practically
> all cases of this type.

Exactly.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.