AVR: __flash / __FLASH Not Recognized in C++

Working on an ATmega328P in an Arduino Uno environment right now.

Rather than the twisted declarations required for PROGMEM and jumping through hoops with *_P variants, I was hoping to use the GCC __flash declarations that have been present since GCC 4.7

https://www.avrfreaks.net/forum/best-way-declare-static-strings

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

Unfortunately, neither __flash nor __FLASH seem to be recognized by the platformio toolchain.

fgrep -r __FLASH ~/.platformio returns nothing. fgrep -r __flash ~/.platformio returns some matches for Digispark “cores” and in the binaries for cc1, cc1plus, and lto1.

Is there something I need to do to enable these compiler extensions in the platformio toolchain?


Build platform is macOS, IDE is CLion, command-line build fails as well.

[env:uno]
platform = atmelavr
board = uno
framework = arduino
$ ~/.platformio/packages/toolchain-atmelavr/bin/avr-g++ --version
avr-g++ (GCC) 5.4.0
$ pio update
Updating tool-scons                      @ 2.20501.4      [Up-to-date]
Updating tool-unity                      @ 1.20403.0      [Up-to-date]

Platform Manager
================
Platform Atmel AVR
--------
Updating atmelavr                        @ 1.12.0         [Up-to-date]
Updating toolchain-atmelavr              @ 1.50400.0      [Up-to-date]
Updating framework-arduinoavr            @ 1.10623.0      [Up-to-date]
Updating tool-avrdude                    @ 1.60300.2      [Up-to-date]


Library Manager
===============

Could try the previous 4.9.2 version of GCC toolchain? Just change your platformio.ini to

[env:uno]
platform = atmelavr@1.11.0
board = uno
framework = arduino

Does it work?

See changes Releases · platformio/platform-atmelavr · GitHub

1 Like

The “blink” example builds with atmelavr@1.11.0.

Adding a check of the define for __FLASH indicates it is not defined. Trying the GCC documentation’s example of declaration of a flash-stored fails to compile.

#include <avr/pgmspace.h> as a long shot changes only the line numbers of the errors.

Edit:

_This functionality apparently works in AVR Studio as seen in https://www.avrfreaks.net/comment/2187486_

I have similar errors with the “known good” const __flash char MenuItem7[] = "Menu Item 7"; from that thread’s lead post.

(Side note: What is the best way to display the current component versions of platformio?)

$ pio run
Processing uno (platform: atmelavr@1.11.0; board: uno; framework: arduino)
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/uno.html
PLATFORM: Atmel AVR > Arduino Uno
SYSTEM: ATMEGA328P 16MHz 2KB RAM (31.50KB Flash)
Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF MODES: FINDER(chain) COMPATIBILITY(soft)
Collected 24 compatible libraries
Scanning dependencies...
No dependencies
Compiling .pioenvs/uno/src/main.cpp.o
src/main.cpp:10:2: warning: #warning __FLASH not defined here [-Wcpp]
#warning __FLASH not defined here
^
src/main.cpp:15:7: error: '__flash' does not name a type
const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };
^
*** [.pioenvs/uno/src/main.cpp.o] Error 1
================================================================= [ERROR] Took 0.59 seconds =================================================================
/*
 * Blink
 * Turns on an LED on for one second,
 * then off for one second, repeatedly.
 */

#include "Arduino.h"

#ifndef __FLASH
#warning __FLASH not defined here
#endif

// Example from
// https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html
const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };

// Set LED_BUILTIN if it is not defined by Arduino framework
// #define LED_BUILTIN 13

void setup()
{
  // initialize LED digital pin as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  // turn the LED on (HIGH is the voltage level)
  digitalWrite(LED_BUILTIN, HIGH);
  // wait for a second
  delay(1000);
  // turn the LED off by making the voltage LOW
  digitalWrite(LED_BUILTIN, LOW);
   // wait for a second
  delay(1000);
}
[env:uno]
platform = atmelavr@1.11.0
board = uno
framework = arduino
$ pio update
Updating tool-scons                      @ 2.20501.4      [Up-to-date]
Updating tool-unity                      @ 1.20403.0      [Up-to-date]

Platform Manager
================
Platform Atmel AVR
--------
Updating atmelavr                        @ 1.12.0         [Up-to-date]
Updating toolchain-atmelavr              @ 1.50400.0      [Up-to-date]
Updating framework-arduinoavr            @ 1.10623.0      [Up-to-date]
Updating tool-avrdude                    @ 1.60300.2      [Up-to-date]

Platform Atmel AVR
--------
Updating atmelavr                        @ 1.11.0         [Detached]
Updating toolchain-atmelavr              @ 1.40902.0      [Up-to-date]
Updating framework-arduinoavr            @ 1.10623.0      [Up-to-date]
Updating tool-avrdude                    @ 1.60300.2      [Up-to-date]

Do they use GCC? Did you try it with Atmel Studio?

I was just looking at that, and though AVR Studio appears to be a Windows offering, it looks like the toolchain uses GCC and can be downloaded for macOS.

$ avr8-gnu-toolchain-darwin_x86_64/bin/avr-gcc --version
avr-gcc (AVR_8_bit_GNU_Toolchain_3.6.2_503) 5.4.0

Looking into how to build with it now.

Edit: I’ll also try to see if AVRfreaks can provide any insight into what I might be missing.

You can replace it in HOME_DIR/.platformio/packages/toolchain-atmelavr. Please keep package.json file without changes.

1 Like

Thanks – same problems, so may well be a problem with environment or code of mine.

Edit:

Digging further, it appears that the __flash functionality is only available in C, not in C++

At least as of five years ago, I didn’t see any work-arounds for C++

https://www.avrfreaks.net/comment/1338776#comment-1338776

https://www.avrfreaks.net/comment/2460341#comment-2460341

Edit:

If anyone else runs into this, I’m dealing with it primarily with the following macros and either manual selection of the matching *_P() call, or use of the __FlashStringHelper cast with certain Arduino-compatible libraries. These macros aren’t guaranteed to work for you, and I may change them in the future, but they at least get around the challenges of the “real” implementation of the PSTR(X) macro in <avr/pgmspace.h>, which doesn’t work in many contexts (“statement-expressions are not allowed outside functions nor in template-argument lists”).

YMMV, wrap with header guards, as appropriate

#include <avr/pgmspace.h>

#define PSTR_INIT( NAME, CONST_STR ) \
namespace _pstr_shadow_vars { static const char NAME[] PROGMEM { CONST_STR }; } \
constexpr PGM_P NAME { &_pstr_shadow_vars::NAME[0] };

#define AS_FLASH_STRING_HELPER( P )  (reinterpret_cast<const __FlashStringHelper * >(P))

Note that ivankravets’ question in the following post was asked before the above edit. As such, I believe it was in reference to the __flash qualifier.

Does it work with our latest GCC 5.4.0?

At least with my knowledge of how platformio works and how the __flash qualifier is supposed to work, even with C (and not C++), I’m unable to get __flash recognized.

(Edit: Through no fault of platformio, I’ll probably be moving current and future development off the AVR platform onto ARM Cortex-M0+, especially as the Cortex-M0+ chips are now less expensive than the AVR chips. As a result, at least for me, this is not a “priority” for platformio resolve.)

$ platformio run --verbose
Processing uno (platform: atmelavr; board: uno)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/uno.html
PLATFORM: Atmel AVR > Arduino Uno
SYSTEM: ATMEGA328P 16MHz 2KB RAM (31.50KB Flash)
Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF MODES: FINDER(chain) COMPATIBILITY(soft)
Collected 0 compatible libraries
Scanning dependencies...
No dependencies
avr-gcc -o .pioenvs/uno/src/main.o -c -std=gnu11 -fno-fat-lto-objects -Os -Wall -ffunction-sections -fdata-sections -flto -mmcu=atmega328p -DF_CPU=16000000L -DPLATFORMIO=30601 -DARDUINO_AVR_UNO -Isrc -Iinclude src/main.c
src/main.c: In function 'main':
src/main.c:6:5: error: '__flash' specified for auto variable 'array'
const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };
^
*** [.pioenvs/uno/src/main.o] Error 1
========================================================================= [ERROR] Took 0.46 seconds =========================================================================

#include <stdio.h>

int
main()
{
    const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };
    volatile int test;
    test = array[2];
    printf("%d\n", test);
}
[env:uno]
platform = atmelavr
board = uno
; framework = arduino
$ ~/.platformio/packages/toolchain-atmelavr/bin/avr-gcc --version
avr-gcc (GCC) 5.4.0