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

PROGMEM/F: section type conflict with __c #3351

Closed
bertmelis opened this issue Jun 13, 2017 · 8 comments
Closed

PROGMEM/F: section type conflict with __c #3351

bertmelis opened this issue Jun 13, 2017 · 8 comments

Comments

@bertmelis
Copy link

bertmelis commented Jun 13, 2017

I haven't got enough understanding of the inner working to assert if this is a coding error, or a bug, but I've got the following:

sketch:

#include "TestClass.h"

TestClass testClass;
const uint32_t INTERVAL = 5000;

void setup() {
  Serial.begin(115200);
  testClass.setPrinter(&Serial);
}

void loop() {
  static uint32_t previousMillis = 0;
  if ((millis() - previousMillis) > INTERVAL) {
    previousMillis = millis();
    testClass.doSomething();
  }
}

TestClass.h:

#pragma once
#include <Arduino.h>


class TestClass {
  public:
    void setPrinter(HardwareSerial* serial);
    void doSomething();
  private:
    static const char* _testString;
    HardwareSerial* _serial;
};

TestClass.cpp:

#include "TestClass.h"

const char* TestClass::_testString PROGMEM = "Test String";

void TestClass::setPrinter(HardwareSerial* serial){
  _serial = serial;
}

void TestClass::doSomething() {
  //do something
  _serial->println(F("testing"));
}

Compiling results in an error: TestClass.cpp:3: error: TestClass::_testString causes a section type conflict with __c

Removing the F macro solved the error as does removing the PROGMEM modifier. However, I'd like to use both. eg: list of error messages and printing small debug messages, both from progmem.

@bertmelis
Copy link
Author

bertmelis commented Jun 13, 2017

OK, it obviously had nothing to do with being is a class (and so being in a seperate file). You just cannot use PROGMEM and F() in the same file. as in this sketch:

const uint32_t INTERVAL = 5000;
const char* testString PROGMEM = "Testing 1 ";

// Print a string from Program Memory directly to save RAM 
void printProgStr (HardwareSerial* serial, const char* str)
{
  char c;
  if (!str) 
    return;
  while ((c = pgm_read_byte(str++)))
    serial->print(c);
}

void setup() {
  Serial.begin(115200);
}

void loop() {
  static uint32_t previousMillis = 0;
  if ((millis() - previousMillis) > INTERVAL) {
    previousMillis = millis();
    printProgStr(&Serial, testString);
    Serial.println(F("Testing_F"));
  }
}

@Makuna
Copy link
Collaborator

Makuna commented Jun 23, 2017

Please see #3369 for a possible solution.

@devyte
Copy link
Collaborator

devyte commented Sep 6, 2017

@bertmelis did you test the solution found in #3369?

@bertmelis
Copy link
Author

Or I just don't understand the solution, or it doesn't solve my "error".

I'm trying to put debug messages in PROGMEM using an array of char pointers, as in Nick Gammon's blogpost. These debug messages are used in a class-library, for now without any namespace defined. I had all the declarations and initialisations in a header file.

@Makuna
Copy link
Collaborator

Makuna commented Sep 14, 2017

While the declaration can be, the initializations can't be in the header; as mentioned in #3369.

@bertmelis
Copy link
Author

But then also: I've got a class method with Serial.println(F("debug text"));. This works untill I inline the method. Despite the proposed solution, it is quite unhandy.

But I'll ask it in another way: are there any thoughts on improving the issue? Or shall I live with it?

(in case of the latter, I'll modify my code to deal with it and close the issue)

@Makuna
Copy link
Collaborator

Makuna commented Sep 18, 2017

You can move the actual string into a const variable that is declared in the header, leaving the Serial.println in place.

This is really what you would want anyhow.

Currently, anything in a F("") will be a duplicated string, even if the text is the same. For any work other than simple examples and sketches, you really want a separate .h/.cpp that contain all your strings.

@devyte
Copy link
Collaborator

devyte commented Feb 28, 2018

Closing due to user error.

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

3 participants