AS6 Compile size and data overflow

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

Compiling within AS4 my program uses approx 6K of data and 23K of program space. After importing into AS6 using the import tool the same program using the same toolchain (WinAVR 20100110) now compiles to 14K of data and 32K of program space and does not fit into an XMega128A1!

Has anyone else come across anything similar? It's not a problem as I will just keep using AS4, just asking, maybe ther's a setting that's changed. All the switches and file list is the same.

Cheers.

John.

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

Apart from optimisation setting it should build almost identically. The real question there is how .data has expanded so much. It sounds like you may be getting two copies of some data items. Could it be that you made the cardinal error of #include'ing .c files somewhere or actually defining data in .h files?

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

No, no includes of .c files anywhere and it is compiled using the same files between the 2 versions of studio. Also I always use the

 
#ifndef BLAH_H
#define BLAH_H

// some defines and prototypes here

#endif

So even if there was data defined, which there isn't it'll only do it once.

I might just reconstruct the program from scratch using the files and see what happens.

I do use memory allocation to reach the bootloader section and to put some data in program memory at a specific location but that should not affect the data and it looks like it has taken the settings in ok according to the linker config.

Thanks.

John.

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

Quote:

So even if there was data defined, which there isn't it'll only do it once.

Once per compilation unit that is! (and that's kind of the point of why putting data/code defintions rather than declarations in a .h is a no-no).

As for the problem the .map file will reveal a LOT (unless everything's hidden behind "static"). Also consider "avr-nm --size-sort project.elf" as it shows you what the "big stuff" is and you can compare sizes of the big stuff from one build with the big stuff from the other.

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

OK, I'm not aware of the once per compilation unit thing, is that per object file? I haven't got any code or data defined except some extern references.
Ive just been scanning the map files to see if I can sus it out, what should I be looking for specifically? I can tell you that the .o files are not consistant in size between the 2 builds also I do tend to declare a variable as static that is in scope of a .c file. Would this not help?

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

Quote:

is that per object file?

Yes. If you had:

// foo.h
int n = 12345;

void a_function(void) {
  POTRB = 3;
}

then:

// bar1.c
#include "foo.h"

void other_function(void) {
  PORTB = 5;
}

and

// bar2.c
#include "foo.h"

int main(void) {
 a_function();
 other_function();
}

then both bar1.o and bar2.o would hold copies of "n" and "a_function".

The linker would warn you about this though when it tried to link the .o files unless the items were "static" in which case each would get private copies bloating the code and confusing things if access were made to "n" in each as they'd be different "n"s etc.

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

OK, cool, i understand the problem but I kinda knew that stuff would happen and haven't fallen into that trap.
I'm interested in the 'avr-nm --size-sort project.elf' statement you mentioned earlier, how do I use that exactly?

Sorry... I do feel like I'm wasting time here but there is a little inquisitive squirrel inside my head wondering what is going on.

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

Quote:

I'm interested in the 'avr-nm --size-sort project.elf' statement you mentioned earlier, how do I use that exactly?


Start a command prompt. Switch to the build directory for the project using CD. Only you know the real project name but whatever it is replace "project.elf" above with that name and issue the command. Here's an example:

C:\Documents and Settings\asl\My Documents\Atmel Studio\GccApplication1\GccApplication1\Debug>avr-nm --size-sort GccAppl
ication1.elf
00000002 T extern_func
00000002 D s1
00000002 D s2
00000002 D s3
00000006 T function
0000001a T main

That's a bit of a boring example as the entire program only has three functions ("T") called extern_func(), function() and main() with main() being the largest at 0x1A bytes long.

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

Ah, possibly got it. There is an 8K chunk of program memory declared as const data which kinda fits the difference. Maybe I haven't declared it correctly and it thinks that it's located in ram.

i declared it like this:

const int16_t vm_program_mem[VM_PROGRAMS][VM_PROGRAM_SIZE] __attribute__((section ("vm_prog")));

where 'vm_prog' is defined as a flash memory location 0x4000.

edit:

Confirmed by changing the array size.

edit 2:

Strangely this array has always effectively been a single dimension as VM_PROGRAMS has never been anything other than 1. Removing the first set of brackets making it a single dimension array and making other obvious program changes seems to make the problem go away and compiles with the expected amount of data.

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

Actually I tried the solution of taking out the array dimension again this morning and it doesn't work! However what I had done was copy a similar statement from another program which had compiled ok that was pretty much identical except that the array elements were initialised:

const int16_t vm_program_mem[VM_PROGRAM_SIZE] __attribute__((section ("vm_prog"))) = {[0 ... VM_PROGRAM_SIZE - 1] = 0};

I thought I had commented out the initialiser and looked no further when it compiled but maybe not as it is infact removing the initialiser that makes the 8K difference in ram usage.

It still confuses me as in theory both versions of studio use the same toolchain so the behaviour when compiled should be the same. I also have run the .lss though diffmerge to see why the ROM usage is different and both listings are identical with exception of a few bytes in the .debug_xxxxx sections.

edit:

Looking at this further, I created a new project....

Attaching the PROGMEM directive to the end of a variable declaration, I thought is the same as typing __attribute__((section (".text"))) and when substituting either seems to have the same effect on the program memory usage and no data is used up. If i create a new flash memory section under the linker settings called .BLAH=0x4000 and then use the __attribute__((section (".BLAH"))) it causes both the program usage and data usage to account for this array. Is there another setting that needs to be changed to get this to work properly?

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

If you .BLAH=0x4000 does this define a symbol or does it define a section start address?

Wow does your IDE handle orphan sections like vm_prog?

Did you verity the location of the object in the map file?

Does -fno-tree-switch-conversion has in impact on RAM usage?

avrfreaks does not support Opera. Profile inactive.

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

PROGMEM is a synonym for __attribute__((progmem)) which is itself sort of equivalent to __attribute__((section(".progmem.data"))) theon the linker script arranges that to be a component of .text but it is not a direct equivalent to __attribute__((section(".text")))

I typed the above on an iPad which just confirms my belief that the iPad keyboard is the worst ever invented!

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

Ok, so maybe I'm not putting this together correctly... What my intention to do, and has previously worked sucessfuly when compiled in AVR Studio 4 is to reserve a chunk of program data that I can read in and use as a program that contains information and a set of instructions for a virtual machine.

The .BLAH=0x4000 (or actually vm_prog) was originally set under the memory segments in the project options of AS4. The array seemed to work fine, the map showed the section at the correct location and correct length. As it worked fine I have never thought any more of it until now.

It would be nice to know why it doesn't work as I expected it to anymore as there could be other things going on. Maybe it worked in AVR Studio 4 when it wasnt supposed to and AS6 has thrown it out, perhaps there is a correct way of acheiving what I want to do? It also seems a bit odd that initialising the array causes it to behave the way I want it to when in AS4 it didn't make any difference either way.

I'm sure iPad would be great if it had a seperate keyboard and mouse and a stand for the screen.