5

In this code for heating monitor, there appears to be macros called FLASH_ARRAY and FLASH_TABLE. I can't find any reference to them either in this code, Arduino, or on the Internet. What do they do?

FLASH_ARRAY(byte, VARIABLE_DEVICE_TABLE,
    DEVICE_LADDNING_RETUR,
    DEVICE_LADDNING_UT,
    DEVICE_TANK1,
    DEVICE_TANK2,
    ...
    VARIABLE_ID_LOAD,
    VARIABLE_ID_TIME_EMPTY);

and

FLASH_TABLE(byte, NUMBER_TEMP_TABLE, 7,
  {DEVICE_LADDNING_RETUR, 99,  5, 10,  7, MAIN_TYPE_TEXT_CELCIUS, 2},
  {DEVICE_LADDNING_UT,    99, 43, 10,  7, MAIN_TYPE_TEXT_CELCIUS, 2},
  ...
  {DEVICE_UTE,             0, 55, 15,  7, MAIN_TYPE_TEXT_CELCIUS_WITH_NEGATIVE, 103},
  {VARIABLE_ID_EFFECT,   114, 29, 10,  7, MAIN_TYPE_TEXT_VARIABLE, 2});
Paolo Zanchi
  • 951
  • 8
  • 22
Cybergibbons
  • 5,420
  • 7
  • 34
  • 51

2 Answers2

5

After further digging, this appears to be from Mikal Hart's Flash library.

The reason this library was developed is:

Storing static program data in flash/PROGMEM is a tricky part of Arduino programming. To save precious RAM, a novice user already at odds with unfamiliar C++ syntax must digest such daunting concepts as prog_char, PSTR(), PROGMEM, pgm_read_word(), etc. Even seasoned users get tripped up by the indirection and typecasting that are required to retrieve valid PROGMEM data. Add to that a couple of apparent bugs in the implementation, and it’s clear that PROGMEM is a complicated mess.

I have written a new library, Flash, which abstracts away most of this complexity. It provides new String, Array, Table, and String Array types that make ROM-based data collections as easy to use as “normal” types. Each overrides the C++ [] operator, so to extract individual elements one uses familiar array access syntax:

Specifically, these are macros and a simple helper class to make it easier to create arrays and tables of values in program memory.

The two macros are declared as so:

// Example: FLASH_ARRAY(float, temperatures, 98.1, 98.5, 99.1, 102.1);
#define FLASH_ARRAY(type, name, values...) \
  static const type name##_flash[] PROGMEM = { values }; \
  _FLASH_ARRAY<type> name(name##_flash, sizeof(name##_flash) / sizeof(type));

// Example: FLASH_TABLE(uint8_t, fonts, 7, {ON, OFF, ON, ON, OFF, ON, OFF}, {OFF, ON, OFF, ON, OFF, ON, OFF}); #define FLASH_TABLE(type, name, cols, values...)
static const type name##_flash[][cols] PROGMEM = { values };
_FLASH_TABLE<type> name((const PROGMEM type *)name##_flash, sizeof(name##_flash) / sizeof(name##_flash[0]), cols);

The helper functions include size and override the operator [] so that they can easily be accessed like so

FLASH_ARRAY[0]

I disagree with zmo - this is more than boilerplate. The area of PROGMEM causes a lot of questions from Arduino users, and it is very easy to do things wrong when creating arrays in PROGMEM.

Cybergibbons
  • 5,420
  • 7
  • 34
  • 51
4

The flash array is from Mikal Hart's flash library as you show, and what it does is that they declare an array or a matrix (table) object in the PROGMEM memory:

#define FLASH_ARRAY(type, name, values...) \
static const type name##_flash[] PROGMEM = { values }; \
_FLASH_ARRAY<type> name(name##_flash, sizeof(name##_flash) / sizeof(type));

which is an instance of the _FLASH_ARRAY class defined in that same file, which is a facility to access PROGMEM/Flash memory.

Basically, it's a lot of boilerplate for what already does the PSTR() macro amongst other from pgmspace.h. I personally would avoid using that and prefer to use the original macros along with my own index and pointers.

BTW, except for some Arduono IDE magic, I don't think that can compile, as the Flash.h is not included.

EDIT:

To make another point against the FLASH_TABLE/FLASH_ARRAY boilerplate/overhead, since avc-gcc 4.8 has been introduced the __flash qualifier which is a replacement for the PROGMEM macro, simplifying the whole stuff:

// to use string literals without having to cast
#define FSTR(X) ((const __flash char[]) { X })

// create string pstr in the .progmem.data address space
const __flash char* pstr = FSTR ("foo"); 

and no more use of the pgm_read_*() functions, you can now access the content of the flash memory using *pstr, as shown is this thread. In case you want to keep a code compatible with older version of avr-gcc, here's a post that offers macros to deal with both systems.

per1234
  • 4,278
  • 2
  • 24
  • 43
zmo
  • 1,518
  • 10
  • 16