Error: __c causes a section type conflict

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Freaks,

Here's a new one. Until today, my rather complicated code has compiled fine. However, I'm now getting the following build error (some compile switches removed as they were just -D token defines):

Compiling C: RNDISEthernet.c
avr-gcc -c -mmcu=at90usb1287 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums -finline-limit=20 -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=./RNDISEthernet.lst -I../../ -std=gnu99 -Wundef -MMD -MP -MF .dep/RNDISEthernet.o.d RNDISEthernet.c -o RNDISEthernet.o 
RNDISEthernet.c:110: error: __c causes a section type conflict
make.exe: *** [RNDISEthernet.o] Error 1

The line in question is:

printf_P(PSTR("\r\n\r\n****** RNDIS Demo running. ******\r\n"));

This works fine elsewhere - I've got a number of similar USART debugging lines throughout the 20 or so source files. Again, this compiled fine until today.

I've double checked that all the appropriate headers are being included (pgmspace.h and stdio.h) and tried a complete clean/rebuild, to no avail.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IIRC, that "__c" part is internally a part of that PSTR macro.

Try defining your string outside of the function, in the program space, and just use that variable in the print_P call. In other words, rearrange your code to avoid using the PSTR macro. Then see if you still get an error.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yep - it's the PSTR that does it. The odd thing is that I have the exact same construct else where in the program (different source files) as well as other projects, and it works fine. While I could change the above, I'd rather keep it as-is so that it matches the other demos in the library.

Any idea why the macro would be failing in this particular instance but not in others?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well darn, now it's happening to all instances of that construct in all the demos. Is this just a case of a broken WinAVR install, or something else easily fixable?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure without looking at your code.

Long ago, after running into similar problems I took a close look at the PSTR macro. While that macro is very clever, and can work in many situations, there are just some things about it I really don't like. I asked myself: "If this were not wrapped up in a macro, and the code just inlined in my application, would I accept this type of code in my application?". My answer would be no. So now, I avoid the PSTR macro like the plague. In my apps I usually have a header file dedicated to string declarations (outside the scope of any functions) and then I don't encounter any weird problems with strings.

For me, the "convenience" of using the PSTR macro is not worth the potential problems it can bring. YMMV.

Eric

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Eric -

I don't understand how you deal with this in headers. Could you elaborate?

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can email my code to anyone who thinks they can help. It's quite extensive, however I do not think it is the code itself which is causing problems.

What's really funky, is that I can't even use normal global constructs for the PROGMEM strings anymore in the demos - I get the same error on something like this:

const char A[] PROGMEM = "B";

Which happens in all the MyUSB code and demos, but not in other projects. Ghost in the machine?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-gcc -E ?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser wrote:
Ghost in the machine?

I don't believe in a Deus Ex Machina. Keeps me from anthropomorphizing these things and giving them too much power than they are credited for.

Feel free to send me your code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll do a wild guess.

Somewhere you have a missing or superfluous ( ) { } ; , " ' which is throwing off the compiler some place later.

Go back in time in your version control system (you do have one, don't you?) until you find a version of the code that still compiles. Then ask the version control system what you changed between the last version that compiled and the first one that doesn't.

If that doesn't work you can start to manually account for all your brackets, etc. Or start cutting out code until the remains compile again. Then carefully add the pieces you cut out one by one.

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
Eric -

I don't understand how you deal with this in headers. Could you elaborate?

Jim

Sure.

Let us have 2 C files: main.c, foo.c. Let us also have a single header file that will contain all definitions of text that we want to store in flash. Let us call this file text.h.

Here are the contents of main.c:

#define MAIN_C

// Include files.
#include "text.h"
#include "whatever.h"
//...

// ... blah, blah, blah

int main(void)
{
   // ...
}

The important thing to note is that I start off the file with a #define of MAIN_C. And all include files come after this definition. This will be important later.

Here are the contents of text.h:

#ifndef TEXT_H
#define TEXT_H

#include 
#include 

#ifdef MAIN_C
    #define global_text(sym, value)   const uint8_t sym[] PROGMEM = value
#else
    #define global_text(sym, value)   extern const uint8_t sym[] PROGMEM
#endif

global_text(txt_prompt_baud, "BAUD: ");
global_text(txt_prompt_flow, "FLOW: ");
global_text(txt_prompt_parity, "PARITY: ");

global_text(txt_38400, "38400");
global_text(txt_19200, "19200");
global_text(txt_9600, "9600");
global_text(txt_4800, "4800");
global_text(txt_2400, "2400");
global_text(txt_1200, "1200");

#endif

The first thing in any good header file is the idempotent guard:

#ifndef TEXT_H
#define TEXT_H
// All contents here ...
#endif

That way you can include the header file as many times as you like (whether on purpose, or by accident), and you won't get multiple definitions.

The next thing are inclusions of a couple of system files that we will need. One for program space definitions and the other for types.

The next is the real magic of the whole system. We are going to define a macro, global_text(), that takes 2 arguments. However, we are going to define the macro differently, depending on whether the symbol MAIN_C is defined, or not defined.

The macro global_text() takes two arguments, sym and value. sym is the symbol name of a variable that we are defining. value is the value that will be assigned to sym.

If MAIN_C is defined, sym will be defined as an array of characters (a string), that will be placed in the Program Memory space, and value will be assigned to the variable sym. It is important to note that this is the definition of the variable.

If MAIN_C is NOT defined, sym will be declared as external and have the same type as the definition. Note that the value parameter is not being used at all in this version of the macro.

Something else to remember is that both definitions of the macro do not end in a semicolon. The semicolon will be provided by the user when the macros are being used.

After this, the macro global_text() is being used. Here are some examples of text that are being defined. These text strings look like they can be used to display UART prompts and values. There are text strings like "BAUD: ", "FLOW: ", and "PARITY: ", with text strings for various baud rate numbers.

The general idea is this: There is only one single place where the variable name, and the associated string, is defined. When this header file is included in main.c, after the MAIN_C definition, then the global_text() macro will expand to the actual definition of the string. When the header file is included in other C files, like foo.c, the MAIN_C definition will be absent, and then the global_text() macro will be expanded to produce an external reference to the string.

The main advantage of this system is it reduces maintenance overhead. If I need to add strings, or change a string, I only have to change it in one place in the text.h header file. There is less chance for errors. And I can easily see all of the text strings that I am storing in Flash, so I can get a quick feel for how much I am storing there.

These string variable names can then be used in other C files. For example we can define foo.c like so:

#define FOO_C
#include 
#include "text.h"

void foo(void)
{
    // ...
    printf_P(txt_prompt_baud);
    printf_P(txt_38400);
    // ...
}

Hope this helps.

Eric Weddington

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very enlightening.

Thank you!
Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sending my code now Eric - thanks for the offer! There is a LOT of code in the library and demos, but I'm sure the problem will be something trivial and 99.99999% of the code will be entirely irrelevant to the issue at hand.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Got it! Eric pointed out that my BUTTLOADTAG macros were causing problems also, even though they don't make use of the PSTR macro at all. I had a look and it turns out I managed to sneak in a "volatile" into the macro definition a while ago in a futile effort to stop the compiler from removing it from the binary. Removing that fixed all the problems.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!