Compiling errors

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

Ok so I am attempting to hop back into micro controller programming. I have done a fair bit with mplab back in the day. But for whatever reason I was asked to use avr equipment so I am.

That being said I was asked to translate a asm program into C for more flexibility.

So far I have just dont a tonne of defines that were used in the asm program to set up prescalers etc and port setting etc. I am splitting my source files for organisational reasons. I have so far 3, main.c, inc.c, setup.c.

The problem is that the compiler, is not doing them in the order I included them. Its doing setup first, which is causing declaration errors. I was under the impression compilers looked for the file with main() then went from there. But it isn't, so any help would be lovely!

Cheers

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

Quote:

is not doing them in the order I included them. Its doing setup first, which is causing declaration errors.
If the order matters you are doing it wrong! A linking compiler compiles each .c file individually - each one has no visibility of the other. If they have details to be shared then those details (none storage allocating!) should be in .h files. It is true that the order of inclusion of .h files may matter.

Sounds like you may benefit from reading an article in the Tutorial Forum called "Managing large projects" which tells you how to split a program across several .c files and concepts such as "extern".

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

Ok I have read the tutorial, and i will likely do that what is said and get back if I have issues.

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

Alright I fixed it up pretty good, following that very handy guide. Fixed up all my headers and prototypes etc. but I am getting one error saying I am declaring something multiple times. After searching people seem to always point at the headers. All I have there is a simple function prototype. Please see code:

setup.h

#ifndef SETUP_H
#define SETUP_H

#include 
#include 
#include "general.h"
#include "inc.h"

void Setup(void);

#endif

setup.c

#include "setup.h"

//prototypes

//void Setup(void);
static void ioSetup(void);
static void timer0Setup(void);
static void timer1Setup(void);
static void eepromSetup(void);
static void acSetup(void);
static void uartSetup(void);

//Calls all the other setup functions

void Setup(void)
{
	ioSetup();
	timer0Setup();
	timer1Setup();
	eepromSetup();
	acSetup();
	uartSetup();
}

main.c

#include 
#include 
#include 
#include 
#include 
#include 
#include "general.h"
#include "inc.h"
#include "setup.h"
#include "C1W_setup.c"
//#include 
//#include 
//#include 



int main (void)
{
		Setup();
        do{
			//blah blah
		}while(1);
}

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

So what IS the error? What is that "something"?

Usually the problem is one of storage allocation by something in a .h that is #include'd in more than one .c

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

Sorry after rereading I agree that was a very unclear statement.

The error says
"C1W_setup.o: In function `ioSetup':
C:\Documents and Settings\...../C1W_setup.c:52: multiple definition of `Setup'"

Thanks

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

Not your problem, but you don't want this line:

#include 

You should specify the chip in the makefile (or the project settings if you are using AVR Studio).

Regards,
Steve A.

The Board helps those that help themselves.

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

Yeah thats a relic from this morning when it was telling me it didn't know what DDRB and PORTB were. I haven't done embedded for 3-4 years so I still shaking off the rust. I have removed the extraneous lines :)

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

Quote:

"C1W_setup.o: In function `ioSetup':
C:\Documents and Settings\...../C1W_setup.c:52: multiple definition of `Setup'"

That's very curious because you have:

void Setup(void)
{
   ioSetup();
   timer0Setup();
   timer1Setup();
   eepromSetup();
   acSetup();
   uartSetup();
} 

Yet the error is saying that "Setup()" is being defined "In function `ioSetup'". That smacks of recursion! Is the ioSetup() definition above Setup() in the setup.c file? Could it have missed a closing brace or something?

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

Nope, what I showed you is the top 20 odd lines all the functions are written below, what I showed. I think that the error is just saying ioSetup() because its the next line down. I commented out all the function calls and it says "C1W_setup.o: In function `Setup':" now.

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

Why not just post the files?

BTW the error message said the redefinition is on line 52. So at least show the first 52 lines of the file.

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

Yeah sure I can load the files no problem. I didn't know if that was appropriate on this forum or not, I saw the code button and assumed it was the common method for sharing code.

Here it is...

Attachment(s): 

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

First thing wrong. C1W_main.c has:

#include "C1W_setup.c"

never #include one .c file in another. This is a linking compiler - let the linker link the code!

However:

E:\C1W>avr-gcc -mmcu=atmega16 C1w_main.c

E:\C1W>

IOW it builds for me without warning or error. That suggests you are building it differently from the way I just did.

I have half a suspicion you are using AVR Studio and you have both C1W_main.c and C1W_setup.c listed in the project. If that's what you've done then first Studio will launch the compiler to compile C1W_main.c and while it's doing it that will #include C1W_setup.c and create copies of the functions it contains in C1W_main.o. Next it will compile C1W_setup.c to create CW1_setup.o and that, too, will contain copies of the functions. Finally the linker will link C1W_main.o with C1W_setup.o and at that moment it will find copies of the C1W_setup functions in BOTH files. This is when it throws the multiply defined error you are seeing.

the solution is simple - just remove the #include of the .c file from the C1W_main.c file and leave it to the linker to join the functions.

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

Thank you sir, I much appreciate the help! But could you clear up something that I think I misunderstood. If I include the file in my project in AVR don't use includes, but if I don't add it I can use includes to add them "manually".

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

Sorry but your question does not make any sense to me. If English is not your first language consider typing the question in your native language.

Bottom line: #include is for includeing .h files. They do not contain any storage allocating code or data but merely document the interface to functions and variables in other C files.

Each .c file is built in complete isolation from all other .c files (except in extraordinary circumstances). In a project there can actually be weeks between one of the files being compiled and the others being built.

When a .c file is built it output a .o file. The code may make references to functions and variables that are not actually available at build time so the .o file contains "markers" (aka "fixups") to say "I need to find a variable called 'foo' and read it here" or "I need to make a call to a function called bar() at this point".

Finally when the complete program is to be built the linker pulls together all the .o files and as it comes across functions and variables it builds a (map) table of where they are located. When it comes to the file that needs to access 'foo' or 'bar()' it looks at the map to see if it has already encountered that variable/function. If so it fills in the "fixup" with the destination address. By the end of the link all referenced functions and variables must have been seen and added to the table. If not then the linker outputs "undefined reference" error. On the other hand if it finds 'foo' or bar() in two different .o files it won't know which one to use and will output a "symbol 'foo' is multiply defined" type of error as you have seen.

(sorry - that's quite a long "bottom line"!)

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

That's good, I was hoping for more in depth information so I am glad you took the time to write it out. As I said I am out of touch with embedded and when I did it it was never very complicated code. And you did answer my question, I was under the impression that I needed to #include my .c code, I misunderstood the role of the .h file.

I was under the impression that adding files to the file browser in AVR was just a convenience and that the #includes were to direct the compiler to the right files. As you mentioned in you answer thats not how it works and I what I was doing was @$$ backwards.

Also I never explicitly stated it before, my code now compiles properly so mission accomplished.

Cheers

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

Just adding a .c file to the tree at the left is enough to add it to the list of files that will individually be passed to the C compiler and that will all then be joined by the linker.