Skip to content

Elements in Flash Memory

Calvin Hass edited this page Sep 16, 2019 · 4 revisions

Starting with release v0.8.2, Arduino-based designs can store read-only GUI elements in Flash (PROGMEM)! Doing so can free up a significant amount of RAM, making it possible to run more complex GUIs even on RAM-constrained Arduino devices (such as the UNO / ATmega328P). To use this feature, simply replace the gslc_ElemCreate*() call with the equivalent gslc_ElemCreate*_P() call. The following functions are supported at this time:

  • gslc_ElemCreateTxt_P()
  • gslc_ElemCreateTxt_P_R() (allows read-write text)
  • gslc_ElemCreateBox_P()
  • gslc_ElemCreateBtnTxt_P()

Once the element create functions have been replaced by the _P() variants, the RAM-based element array (gslc_tsElem[]) can be made smaller as fewer elements need to be resident in RAM. The total number of elements in the element reference array (gslc_tsElemRef[]) will remain unchanged. Finally, the call to gslc_PageAdd() needs to indicate the revised number of RAM-resident elements.

Behind the scenes, the _P() functions are really a set of macros that create a set of data structures to match the non-Flash APIs.

Changes to the Element Creation

Let's start by assuming that a read-only label "Count:" was created on the page as follows:

  pElem = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_MAIN,(gslc_tsRect){20,60,50,10},
    "Count:",0,E_FONT_TXT);

In the above, the entire element (including text string) will be stored in RAM. Alternately, one might performed some optimization by requesting that the text string "Count:" be stored in PROGMEM with the remainder of the element stored in RAM. Code to do this might look like the following:

  static const char mstr2[] PROGMEM = "Count:";
  pElem = gslc_ElemCreateTxt(&m_gui,GSLC_ID_AUTO,E_PG_MAIN,(gslc_tsRect){20,60,50,10},
    (char*)mstr2,strlen_P(mstr2),E_FONT_TXT);
  gslc_ElemSetTxtMem(pElem,GSLC_TXT_MEM_PROG);

To convert the above element creation call into one that stores the entire element in Flash, one can replace the above with the following:

  gslc_ElemCreateTxt_P(m_gui,101,E_PG_MAIN,20,60,50,10,"Count:",0,
         GSLC_COL_YELLOW,GSLC_COL_BLACK,GSLC_COL_BLACK,GSLC_ALIGN_MID_LEFT,false,true);

Note that these "macro functions" handle parameters a little differently than regular functions. One of the main differences is when passing a parameter that includes a comma. One example scenario is when passing a custom RGB color as a parameter: in this case, one might be tempted to pass (gslc_tsColor){255,200,0} instead of GSLC_COL_ORANGE. To avoid any issues with macro expansion, such parameters should be wrapped in parentheses, ie: ((gslc_tsColor){255,200,0}).

Changes to the Initialization

Now assume that there are a total of 14 created elements on the main page (E_PG_MAIN), with all 14 originally defaulting to RAM storage (ie. stored in m_asPageElem[]). We might have allocated space for these elements as follows:

  #define MAX_ELEM_PG_MAIN        14                                        // # Elems total
  gslc_tsElem                 m_asPageElem[MAX_ELEM_PG_MAIN];
  gslc_tsElemRef              m_asPageElemRef[MAX_ELEM_PG_MAIN];
  ...
  gslc_PageAdd(&m_gui,E_PG_MAIN,m_asPageElem,MAX_ELEM_PG_MAIN,m_asPageElemRef,MAX_ELEM_PG_MAIN);

If we then moved 6 of the read-only elements from RAM to Flash (using the gslc_ElemCreate*_P() functions), we could revise our variable declaration and PageAdd to the following:

  #define MAX_ELEM_PG_MAIN        14                                        // # Elems total
  #define MAX_ELEM_PG_MAIN_PROG   6                                         // # Elems in Flash
  #define MAX_ELEM_PG_MAIN_RAM    MAX_ELEM_PG_MAIN - MAX_ELEM_PG_MAIN_PROG  // # Elems in RAM
  gslc_tsElem                 m_asPageElem[MAX_ELEM_PG_MAIN];
  gslc_tsElemRef              m_asPageElemRef[MAX_ELEM_PG_MAIN];
  ...
  gslc_PageAdd(&m_gui,E_PG_MAIN,m_asPageElem,MAX_ELEM_PG_MAIN_RAM,m_asPageElemRef,MAX_ELEM_PG_MAIN);

Note that new #defines have been created to help us calculate the remaining number of elements that need to be stored in the internal RAM element array given a certain number of elements that have been migrated to use Flash.

Parameter list for ElemCreate*_P() functions

Please refer to the online API guide under Flash-based Element Macros

Clone this wiki locally