element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Arduino
  • Products
  • More
Arduino
Blog Saving SRAM by storing data in Program Memory
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Arduino to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Former Member
  • Date Created: 16 Apr 2014 4:50 PM Date Created
  • Views 1754 views
  • Likes 0 likes
  • Comments 0 comments
  • ram
  • small
  • progmem
  • flash
  • sram
  • data
  • arduino
Related
Recommended

Saving SRAM by storing data in Program Memory

Former Member
Former Member
16 Apr 2014

User interfaces can take up a lot of memory. That is why, while developing the Arduino User Interface I focused on developing a way to store things in Program Memory instead. It turns out that storing -- and then using -- program memory objects can be slightly confusing. So I thought I would write a quick post about it.

 

Most people are familiar with the simple use of program memory for strings. Instead of writing

 

Serial.println("This is taking up a lot of mem");

 

You can write

Serial.println(F("This is taking up no mem"));

The F() stores the string in Flash (or Program Memory) instead of creating a character array in RAM and then passing it to println. This is very good, considering that the Arduino UnoArduino Uno has only 2k of SRAM and more than 32k of Program Memory!

 

Storing in Program Memory

But what if you want to do something more? The threading module requires an array of pointers to functions. At first glance, this also looks fairly easy.

typedef int (* funptr)(int index)  // declare the funptr type

 

int return_0(){

  return 0;

}

 

int return_1(){

  return 1;

}

 

PROGMEM const funptr fptrs[] = {&return_0, &return_1, NULL} // fun_x are declared functions

The problem comes about when you have to pass the pointers variable to other functions -- there is no way to declare that it is coming from program memory!

 

Before I explain, perhaps it is a good idea if we remember what a pointer is: it is a number which represents a certain location in memory. So:

 

int x = 8;          // x is storing the integer 8

int *p_x = &x;  // p_x is storing the location of x

 

So right now our fptrs are just an array of data that is stored in Program Memory, each of them pointing to functions.

 

Lets say we have a function like the one below:

 

int call_func(int index, const TH_funptr *ptrs){

     return ptrs[index](); // THIS DOESN'T WORK

}

 

The reason the above code doesn't work is because fptrs are in program memory! To access it we have to read out of program memory. Fortunately, there is a function to read 2 bytes of data (a word) from program memory: pgm_read_word

 

To solve this problem, I developed the get_pointer routine.

 

void *get_pointer(PGM_P s, uint8_t index, uint8_t size){

  return (void *)pgm_read_word(s + index * size);

}

 

So now our function would look like

 

// not very useful, but at least it works

int call_func(int index, const TH_funptr *ptrs){

     return get_pointer((PGM_P)fptrs, index, 2)(); // This works. Note that you have to cast fptrs as type PGM_P

}

 

 

More Complex Storage in Program Memory

 

The Arduino page has an excellent tutorial on how to store strings in program memory, and that is what is fundamentally used in the usertools library. Basically, you must construct each pointer, and then store an array of pointers (tons of fun).

 

This also applies to more complex data types. I would have THOUGHT that you could store basic types in an array, but it turns out you can't. For instance, variables are composed of a pointer to the variable and an 8 bit unsigned integer representing it's size. To store a variable, you have to store a pointer to each element in program memory, and then store the array of those pointers into program memory as well (using way more program memory than I would like, but no RAM).

 

That is the reason to expose variables you have to do:

UI_V(v1, myvar1);              // Variables have to be declared specially. Declare variable names first with UI_V

UI_V(v2, myvar2);              // Variables have to be declared specially. Declare variable names first with UI_V

expose_variables(UI_VA(v1), UI_VA(v2));     // Then wrap the variable names in UI_VA. Alot of things have to be done to take up zero RAM!

 

Now you know what goes into taking up zero RAM.

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube