Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiling error: "in expansion of macro 'F'" #83

Closed
sushukka opened this issue Mar 29, 2018 · 4 comments
Closed

Compiling error: "in expansion of macro 'F'" #83

sushukka opened this issue Mar 29, 2018 · 4 comments

Comments

@sushukka
Copy link

sushukka commented Mar 29, 2018

When trying to compile WS2812FX with MySensors node, I get following error message:

In file included from C:\Omat\Own_projects\Arduino\omat\libraries\MySensors/MySensors.h:28:0,
  from C:\Omat\Own_projects\Arduino\omat\MySensors\HomeNumber_IrRemote\HomeNumber_IrRemote.ino:39:

C:\Users\userxxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/pgmspace.h:21:51: error: __c causes a section type conflict with __c

 #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))

                                                   ^

C:\Omat\Own_projects\Arduino\omat\libraries\MySensors/core/MySensorsCore.h:91:40: note: in definition of macro 'CORE_DEBUG'

 #define CORE_DEBUG(x,...) hwDebugPrint(x, ##__VA_ARGS__) //!< debug

                                        ^

C:\Omat\Own_projects\Arduino\omat\libraries\MySensors/core/MySensorsCore.cpp:594:13: note: in expansion of macro 'PSTR'

  CORE_DEBUG(PSTR("MCO:SLP:WUP=%d\n"), result); // sleep wake-up

             ^

In file included from C:\Users\userxxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Arduino.h:243:0,

                 from sketch\HomeNumber_IrRemote.ino.cpp:1:

C:\Users\userxxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/pgmspace.h:21:51: note: '__c' was declared here

 #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))

                                                   ^

C:\Users\userxxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.h:38:76: note: in definition of macro 'FPSTR'

 #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))

                                                                            ^

C:\Users\userxxx\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.h:39:34: note: in expansion of macro 'PSTR'

 #define F(string_literal) (FPSTR(PSTR(string_literal)))

                                  ^

C:\Omat\Own_projects\Arduino\libraries\WS2812FX-master/WS2812FX.h:284:50: note: in expansion of macro 'F'

       _name[FX_MODE_CUSTOM]                    = F("Custom");

                                                  ^

exit status 1
Error compiling for board WeMos D1 R2 & mini.

Not sure where the problem lies. Have around 100 MySensor nodes and this is the first time I get this error. Something overlapping or...?

@moose4lord
Copy link
Collaborator

This issue has been around for quite a while. See the explanation for this bug here: esp8266/Arduino#3351
Basically, both the WS2812FX library and the MySensors library are putting non-global strings in Flash memory (to conserve RAM memory), which causes a conflict. The link above references a couple workarounds you can investigate. Or you might want to try using Board Manager to upgrade to the latest version of the ESP8266 platform (v2.4.1). They may have fixed this issue in that release.

@sushukka
Copy link
Author

Thanks! Updated to V2.4.1 but the problem persist. Have to dig deeper into the link you provided, but so far it seems that one have to modify more or less the actual source codes of WS2812FX or Mysensors library. For future maintainability/upgradeability I'm not very keen to go that path. But hopefully there will be some neat solution I haven't found yet...

@moose4lord
Copy link
Collaborator

I think you're right about having to modify the library source code. I agree, not a great option for future maintainability. But for the WS2812FX lib it's not terribly hard. You just need to move all the strings out of Flash memory and into RAM memory, i.e. change all the F(...) functions to regular strings and change all the __FlashStringHelper references to char references.

The getModeName() function in WS2812FX.cpp becomes this:

const char* WS2812FX::getModeName(uint8_t m) {
  if(m < MODE_COUNT) {
    return _name[m];
  } else {
    return "";
  }
}

And all the mode strings in WS2812FX.h change to regular strings:

_name[FX_MODE_STATIC]                    = "Static";
_name[FX_MODE_BLINK]                     = "Blink";
_name[FX_MODE_BREATH]                    = "Breath";
...

I'll have to give some thought to changing all the strings in WS2812FX to global variables, so this doesn't continue to be a problem.

@sushukka
Copy link
Author

sushukka commented Mar 31, 2018

Hello,
Thanks a lot for your help! :)
I made the modifications and got still some flashtring errors, but only because I had to make two more changes:
const __FlashStringHelper* getModeName(uint8_t m);
-->
const char* getModeName(uint8_t m);
and
const __FlashStringHelper* _name[MODE_COUNT]; // SRAM footprint: 2 bytes per element
-->
const char* _name[MODE_COUNT]; // SRAM footprint: 2 bytes per element
Now compilation ends ok! Reading your comments in the code I assume that this flashstring stuff is needed with some lower memory controllers (like Nano you commented... :)), but with ESP8266 there are much more playroom. Maybe some AVR check for Nano/similar and then branch to different methods after that...However, the problem would still persist with Nano+MySensors&WS2812FX so probably your global variable solution is the way to go.

@sushukka sushukka closed this as completed Apr 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants