Electronic – Data memory usage reported by AtmelStudio for ATtiny85

atmel-studioattiny85

I am using AtmelStudio to program an ATtiny85, which has 512 bytes of SRAM data memory.

My code includes a large lookup-table (array) which is 512 bytes:

const uint16_t lut[256] = { ... };

The project has no other global or static data, so when I compile it, AtmelStudio reports:

"C:\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-size.exe" "mcp4821_attiny85.elf"
           text    data     bss     dec     hex filename
            242     512       0     754     2f2 mcp4821_attiny85.elf
    Done executing task "RunCompilerTask".
    Using "RunOutputFileVerifyTask" task from assembly "C:\Atmel\Studio\7.0\Extensions\Application\AvrGCC.dll".
    Task "RunOutputFileVerifyTask"
                Program Memory Usage    :   754 bytes   9.2 % Full
                Data Memory Usage       :   512 bytes   100.0 % Full
    Done executing task "RunOutputFileVerifyTask".

As shown, AtmelStudio reports that I have exactly filled my available data memory space. If I make the lut array one element larger, the compiler alerts me of the memory overflow. Conversely, if I make the array one smaller, the compiler reports that I have room to breathe (of two bytes).

However, when I used the code to program the chip, I found that there was indeed a memory corruption, and I received bad data when reading the last 16 bytes of the array.

For testing, the LUT is just a sine wave – and the microcontroller is writing the LUT to a DAC. The glitches in the image below reveal the erroneous data from the bad memory accesses (sorry for the poor image quality):

image showing glitches from bad data

I resolved this problem by following the great advice found here: Memory management problems with ATTiny85

Changing

const uint16_t lut[256] = { ... };

to

#include <avr/pgmspace.h>
const PROGMEM uint16_t lut[256] = { ... };

and using

pgm_read_word()

to access the array elements. But I'm not sure why this is necessary.

My questions are:

  • why doesn't the array fit into the data memory even though AtmelStudio reports no error.
  • and most importantly, why does AtmelStudio report no error?

I suspect the answer to both is related to stack space, but I'm not sure. Thanks.

Best Answer

Even if you define your variables as const, the compiler will still put them into the AVR's RAM. Only if you define your variables with the PROGMEM attribute will it keep the variables only in flash and read them from there.

Your array fits right into the RAM, completely filling it. But as you already suspected, running your main or other functions will use part of the RAM for the stack, probably overwriting your LUT. This is called stack collision and can not be predicted by AtmelStudio, as it has no way of knowing which functions you will call and how often.

If you really need all 512 RAM Bytes and don't want to load from flash, you could write the code to drive the DAC from the LUT in assembler code without using a stack.

For illustration

stack space

graphic borrowed from here

Related Topic