Atmega328p RAM shortage?

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

I’m using an Atmega328p which is communicating with a Bluegiga BLE113 and I’m getting unexpected behaviour. It’s only after a couple days of debugging that I realised that it might be a memory issue. The C library that implements the API to communicate with the BLE113 is very large and I’m thinking that it eats up all my Atmega’s RAM (it contains a lot of global/static variables, like huge arrays of structures). My code works fine when I remove parts of the library so I’m thinking it’s a memory problem. It is eventually my intention to include only those parts of the API that I actually use in my application, in which case the memory problem would disappear. But it would be nice to have access to the full library during development. 

 

I used avr-size to get some memory information about my application and it returned:

 

AVR Memory Usage

----------------

Device: Unknown

Program:   10062 bytes

(.text + .data + .bootloader)

Data:       3752 bytes

(.data + .bss + .noinit)

 

Am I right in assuming that the ‘Program’ part is kept on my flash memory and the ‘Data’ part is the RAM usage? Because this would mean that my application needs 3.7kB of RAM which is a lot more than the 2kB the Atmega actually has. So in short my question is: is the shortage of RAM the reason that my code is behaving unexpectedly or am I totally wrong? And if it is, is there a way to keep my RAM usage down without removing parts of the library?

Last Edited: Wed. Nov 5, 2014 - 11:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So in short my question is: is the shortage of RAM the reason that my code is behaving unexpectedly

Yes.

And if it is, is there a way to keep my RAM usage down without removing parts of the library?

That depends on what exactly is eating up the RAM. If it is constant data, then it can be moved to flash. If not, then can this "global" data be moved to local (assuming that not all of it is needed at any one time).

Regards,
Steve A.

The Board helps those that help themselves.

Last Edited: Thu. Nov 6, 2014 - 01:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Remember that fixed text also is constant data. (depending of compiler use _flash PROGMEM .....)

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

depending of compiler use _flash PROGMEM .....

The compiler is clearly avr-gcc so these days __flash would be the best solution.

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

I've put most of the library in Flash memory and it works fine now. Thanks for the answers!

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

I have been working on graphic LCD project recently that has a similar challenge. Huge arrays of constants that need to be in PROGRAM MEMORY to be workable. This project happens to be ATMEGA328P and GCC as well.

 

I used the pgmspace.h macros to declare the arrays into PROGMEM. All is well as far as storing the data. The part that seems clumsy is retrieving the data. From what I learned, the only way to ready the data is to use the pgm_read_byte(&()) macro. It all seems to work fine but it makes the reading of the data somewhat complicated - having to nest the constant in the macro each time. Is this the normal way of retrieving the data, or am I going about it the hard way?

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

That is how I also do it. I don't know of any other way to do it but I'm still an AVR noob. :)

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

rx8pilot wrote:

I used the pgmspace.h macros to declare the arrays into PROGMEM. All is well as far as storing the data. The part that seems clumsy is retrieving the data. From what I learned, the only way to ready the data is to use the pgm_read_byte(&()) macro. It all seems to work fine but it makes the reading of the data somewhat complicated - having to nest the constant in the macro each time. Is this the normal way of retrieving the data, or am I going about it the hard way?

Current versions of GCC support the __flash declaration modifier. Reading data from a __flash-modified variable is transparent to the programmer.

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

That is great to hear. Much cleaner and I don't have to remember what data is where. Now, I go slog through the GCC docs. One of my favorite Sunday afternoon treats. ;-)

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

Thats is indeed very useful. Why didn't I see that on the GNU website or when I was googling around... Thanks for the info!

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

rx8pilot wrote:
Much cleaner and I don't have to remember what data is where.
Almost.  You still need to use the correct version of functions that take C strings (i.e. pointers to char) as an argument, like printf_P().  But yes, you can avoid pgm_read_*().

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Thank you for the clarification. Those nuggets of experience can help shave a day or two of banging my head against the keyboard. 

 

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

Now, I go slog through the GCC docs.

Not really a "slog". There is only one page in the entire GCC manual that mentions __flash and a Google for "avr gcc __flash" hits it immediately...

 

https://gcc.gnu.org/onlinedocs/g...

 

As it mentions on that page a visit to:

 

https://gcc.gnu.org/onlinedocs/g...

 

is a good idea too as you may well find __builtin_avr_flash_segment() useful if you plan, for example, to write combined routines that take _mmex but then dereference it either as a __flash or RAM pointer.

 

Aside: BTW the person (Georg-Johan Lay) who implemented __flash for us users also wrote this very informative page of information:

 

https://gcc.gnu.org/wiki/avr-gcc

Last Edited: Mon. Nov 10, 2014 - 10:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This "Google" thing is amazing. ;-)

 

You are correct, one page is not bad at all. I am still an intermediate programmer, so even when a Google search pulls something up that seems simple I start to wonder what I am missing. In this case, Google first led me to a few resources [before I knew anything about _FLASH] to the more cumbersome solution of using pgm_read_byte(&()) macro. It is really great to have experienced humans that can throw in a few keywords that drive me straight to the golden information. The "slog" reference was about the entire round trip of finding a solution and then verifying that it actually is the best solution and then second guessing myself because I am only modestly experienced.