Progmem with winAVR not saving RAM?

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

Hi, I am running an xmega256A3 and having a bit of trouble getting the progmem attribute to actually save RAM

I made a test that continually mallocs and frees a variable "memtest". Each time this is malloc's I make it 100 bytes bigger until finally "memTest == NULL". This allows me to test the biggest amount of memory I can get (i.e. the clean RAM space left). I don't free memory anywhere else in the code so memory shouldn't be fragmented.
Note:
the array "string" is declared as volatile.
"PERCENT" and "NEW_LINE" are only in text code because I think the percent symbol and "slash r slash n" were giving me bad requests when I tried to preview this post.

if(!context->completedMemTest)
{
	char *memtest = NULL;
	unsigned int size = 100;
	memtest = (char *)malloc(size);

	while (memtest != NULL)
	{
		free(memtest);
		size+=100;
		memtest = (char *)malloc(size);
	}
	free(memtest);
	size-=100;
	sprintf((char*) string, "Memory left (+-100b) = " PERCENT "ub, stack size = " PERCENT "u" NEW_LINE, size, (unsigned int)(0x5FFF-((((unsigned int)SPH)<<8)|SPL)));
	buffer_addString(context->debugOutputBuffer, (char*) string);
	context->completedMemTest = true;
	if(volatileTrue)
	{
		//RAM
		//static const char bigString[] = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I AM A REALLY BIG STRING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " NEW_LINE;
		//strcpy((char*) string, bigString);
		
		//ROM
		//static const char bigString[] PROGMEM = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I AM A REALLY BIG STRING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " NEW_LINE;
		//strcpy_P((char*) string, bigString);

		/*
		//Inline RAM
		strcpy((char*) string, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I AM A REALLY BIG STRING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " NEW_LINE);
		strcpy((char*) string, "abcdefghijklmnopqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyz" NEW_LINE);
		strcpy((char*) string, "zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba" NEW_LINE);
		strcpy((char*) string, "qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm" NEW_LINE);
		strcpy((char*) string, "mnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewq" NEW_LINE);
		*/
		
		///*
		//Inline ROM
		strcpy_P((char*) string, PSTR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I AM A REALLY BIG STRING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " NEW_LINE));
		strcpy_P((char*) string, PSTR("abcdefghijklmnopqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyzabcdefghijklmpnoqrstuvwxyz" NEW_LINE));
		strcpy_P((char*) string, PSTR("zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba" NEW_LINE));
		strcpy_P((char*) string, PSTR("qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm" NEW_LINE));
		strcpy_P((char*) string, PSTR("mnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewqmnbvcxzlkjhgfdsapoiuytrewq" NEW_LINE));
		//*/
		
		buffer_addString(context->debugOutputBuffer, "Done" NEW_LINE);
	}
}

When I run this code (using only the inline ram or inline rom sections, from memory get the same results with non-inline code) I get some interesting results depending on what compiler I use:

    Inline RAM, AVR Toolchain

    AVR Memory Usage
    ----------------
    Device: atxmega256a3

    Program: 59850 bytes (22.1% Full)
    (.text + .data + .bootloader)

    Data: 3844 bytes (23.5% Full)
    (.data + .bss + .noinit)

    Print out:
    Start
    Memory left (+-100b) = 11900b, stack size = 21
    Done

    Inline RAM, WinAVR 2010

    AVR Memory Usage
    ----------------
    Device: atxmega256a3

    Program: 60348 bytes (22.3% Full)
    (.text + .data + .bootloader)

    Data: 3844 bytes (23.5% Full)
    (.data + .bss + .noinit)

    Print out:
    Start
    Memory left (+-100b) = 9500b, stack size = 21
    Done

    Inline ROM, AVR Toolchain

    AVR Memory Usage
    ----------------
    Device: atxmega256a3

    Program: 59852 bytes (22.1% Full)
    (.text + .data + .bootloader)

    Data: 2656 bytes (16.2% Full)
    (.data + .bss + .noinit)

    Print out:
    Start
    Memory left (+-100b) = 13100b, stack size = 21
    Done

    Inline ROM, WinAVR 2010

    AVR Memory Usage
    ----------------
    Device: atxmega256a3

    Program: 60350 bytes (22.3% Full)
    (.text + .data + .bootloader)

    Data: 2656 bytes (16.2% Full)
    (.data + .bss + .noinit)

    Print out:
    Start
    Memory left (+-100b) = 9500b, stack size = 21
    Done

So the progmem seems to perform properly with the ARV toolchain, the DATA usage drops by ~1200bytes and the available memory from my test goes up by ~1200bytes. However with the winAVR toolchain the DATA usage "apparently" drops by ~1200bytes but the available memory from my test stays the same.

Have I done something wrong here?
Is this a known issue?

Also my test shows a lot more free ram when compiled by the ARV toolchain without even considering progmem?

I have attached the main c file + make and build files
NOTE: The avr toolchain came with avr studio 5

Attachment(s): 

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

I've also found this in prgspace.h in the avr toolchain (avr-libc 1.7.1)

Quote:
\note For Xmega devices, make sure the NVM controller command register (\c NVM.CMD or \c NVM_CMD) is set to 0x00 (NOP) before using any of these functions.

Would this be to do with my problem?