Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: section type conflict

  1. #1
    Senior Member
    Join Date
    Apr 2019
    Posts
    110

    section type conflict

    Hello I'm getting a section type conflict error when I compile on T4.1 : VELOCITY causes a section type conflict with CHORD_DETUNE_STR


    If I add another declaration marked PROGMEM in one file, I get the conflict with the declaration in another.

    In Velocity.h:
    Code:
    const static float VELOCITY[5][128] PROGMEM = {
      {1.0f, 1.0f, ................cut out.......................   1.00f, 1.00f}
    };

    In Detune.h:
    Code:
    const static String CHORD_DETUNE_STR[128] PROGMEM = {"Major", ..........cut out.............. "Oct - 1 - 2"};

    Any help appreciated thanks.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,637
    Maybe you have more PROGMEM elsewhere in the same file? Just a blind guess, maybe you're also using PROGMEM on functions? (where you should use FLASHMEM only for functions and PROGMEM only for variables)

  3. #3
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    Yes, I've got more PROGMEMs. Adding another in Detune.h caused it. No PROGMEM on functions but I've got FLASHMEM on a number of functions in several files. Trying to allow more memory!

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,609
    I ran into this as well once in some sample code I was doing. Not sure how I resolved it. I may have punted and removed the progmem... Or maybe I removed the word static...

    Again I don't remember how I resolved it.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,637
    It'd be quite a miracle if anyone could figure this one out from only the info on this thread. If you want us to help more, you're going to have to show us the complete code.

    Please consider the way we're albe to help falls into 3 broad categories. We can reproduce the problem, or we can see the problem even if we don't have enough code to reproduce it, or we can only guess the problem because we can't see enough of the info. So far, this is definitely into the guesswork range.

    If you want better help, give us complete code we can copy it into Arduino and reproduce the error message.

  6. #6
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,450
    Like KurtE, I have also run into this but can't remember which sketch or how I fixed it.

    But this compiles:
    velocity.h
    Code:
    const static float VELOCITY[2][5] PROGMEM = {
      {1.0f, 1.0f, 1.00f, 1.00f, 1.00f },
      {1.0f, 1.0f, 1.00f, 1.00f, 1.00f },
    };
    detune.h
    Code:
    const static String CHORD_DETUNE_STR[2] PROGMEM = {"Major", "Oct - 1 - 2"};
    sketch
    Code:
    #include "velocity.h"
    #include "detune.h"
    
    void setup(void)
    {
      Serial.begin(9600);
      while(!Serial);
      delay(1000);
    
      Serial.println(CHORD_DETUNE_STR[0]);
      Serial.printf("%8.3f\n",VELOCITY[0]);
    }
    
    void loop(void)
    {
    }
    Pete

  7. #7
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    Hello, the code is available here if anyone wants to take investigation further: https://github.com/ElectroTechnique/.../master/TSynth. I'm not using PROGMEM on the declaration which has fixed the problem and doesn't appear to affect the claimed memory usage, so I assume the compiler is leaving it in flash.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,637
    I downloaded the code and looked briefly. But when I try to find the place to add PROGMEM to reproduce the problem, I can't find "CHORD_DETUNE_STR" anywhere in the code. Looks like you changed it to CDT_STR and the data type is very different from what's been discussed on this thread.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,637
    I did manage to reproduce the error by adding PROGMEM to CDT_STR. To avoid the section type conflict, you need the pointers values to be const. As defined, the pointers point to const data, but the pointers themselves are not const. They could be changed at runtime to point to any other const char data. That is why the compiler is not willing to put your array into flash memory!

    This is the definition you need:

    Code:
    static const char * const CDT_STR[128] PROGMEM = { /*....*/
    The first "const" means the data the pointer references must not change. The pointer can't be used to alter whatever it points to. The second "const" means the pointer can never be changed to point to anything else. For placing the pointer in flash, this second const is what really matters.

    However, this only places the array of pointers into flash memory. The string constants aren't necessarily in flash memory. To understand why, here's a small program to run.

    Code:
    static const char * const list[3] PROGMEM = {
      "test1", "test2", "test3"
    };
    
    void setup() {
      while (!Serial) ; // wait
      Serial.print("list[0] value is: ");
      Serial.println(list[0]);
      Serial.print("list[0] location is: ");
      Serial.println((int)list[0], HEX);
      Serial.print("list location is: ");
      Serial.println((int)list, HEX);
    }
    
    void loop() {
    }
    If you try this on Teensy 4.1, you'll see it prints this to the serial monitor:

    list[0] value is: test1
    list[0] location is: 20000014
    list location is: 600019E4
    The array of pointers is actually in flash memory (which starts at 60000000), but the string it points to is located in DTCM RAM (which starts at 20000000).

    To get both the array of pointers and the strings they reference all into flash memory, you would need this much less convenient syntax:

    Code:
    static const char str0[] PROGMEM = "test1";
    static const char str1[] PROGMEM = "test2";
    static const char str2[] PROGMEM = "test3";
    
    static const char * const list[3] PROGMEM = {
      str0, str1, str2
    };
    
    void setup() {
      while (!Serial) ; // wait
      Serial.print("list[0] value is: ");
      Serial.println(list[0]);
      Serial.print("list[0] location is: ");
      Serial.println((int)list[0], HEX);
      Serial.print("list location is: ");
      Serial.println((int)list, HEX);
    }
    
    void loop() {
    }
    Each string needs a PROGMEM to force it to be placed in flash memory. Then you can create the array of pointers and put that into flash memory too. For the array, the compiler just puts a list of memory addresses into the array. Even though the array definition has PROGMEM, that PROGMEM on the array doesn't have any effect actual memory address numbers which the compiler puts into the array. It only means the list itself will be put into flash. The addresses on the list could be anything. You could even have some of the pointers to strings in PROGMEM and other string in RAM. To get the strings themselves into flash, each one needs an explicit definition so you can use PROGMEM.

  10. #10
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    Ok, that makes sense. Thanks very much for your time.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •