Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Error of multiple definitions in PIC

Status
Not open for further replies.

scorrpeio

Full Member level 5
Joined
Dec 26, 2006
Messages
286
Helped
10
Reputation
20
Reaction score
9
Trophy points
1,298
Activity points
3,496
I have written a code of GSM interface in C for PIC18.

In short the architecture is...

INTERRUPT.h contains the variables as...

Code:
//***uint8_t is typedef of  char ***
uint8_t  G_ui8_RxBufCnt		=	0;
uint8_t  G_ui8_RecvBuf[100]	=	{" "};

I have used these variables in GSM.c file where I included GSM.h.
In GSM.h, I declared above variables as extern...
Code:
extern  uint8_t  G_ui8_RxBufCnt;
extern  uint8_t  G_ui8_RecvBuf[100];

But when I compile...I get an error...

Error - symbol 'G_ui8_RxBufCnt' has multiple definitions.


I have tried by removing the initialisation at the time of declaration of variables, but it didnt work. I think, there is an issue with extern or #include, but could not trace exactly.
Please tell me, how should I proceed to correct the error
 

your are probably including INTERRUPT.h in more than one .c file hence you get multiple defined definitions
put the externs in the INTERUPT.H file
Code:
extern  uint8_t  G_ui8_RxBufCnt;
extern  uint8_t  G_ui8_RecvBuf[100];
and the definitions in GSM.C file
Code:
//***uint8_t is typedef of  char ***
uint8_t  G_ui8_RxBufCnt		=	0;
uint8_t  G_ui8_RecvBuf[100]	=	{" "};
you can then include INTERUPT.H as many times as required
 
Hi.
A good rule of thumb to stick to is to never write source in a header file that would generate machine code and/or take up storage.

You should only put macrodefinitions, type definitions, function prototypes, extern declarations etc. in a header file (none of the above will generate machine code or take up memory).
Additionally, at the beginning of every "header.h" put a
Code:
[COLOR="#006400"]#ifndef[/COLOR] _HEADER_H_
[COLOR="#006400"]#define[/COLOR] _HEADER_H_
and then you end the file with
Code:
[COLOR="#006400"]#endif[/COLOR]	[COLOR="gray"]// #ifndef _HEADER_H_[/COLOR]
(You'll change the definition above to match your file name.)
This way you will prevent multiple inclusions of the same header file.

In your particular case I think you both inlcuded the file with the variable declarations and declared them as external to this module, so the compiler is confused.

In general, if you declare variables or write source that translates to machine code in a header file, that code will be duplicated everytime you include that particular header file. So you'll most likely get an error if don't adhere to the rules above and include a file multiple times.

Arthur
 
Yes..you guessed it right...I have included the INTERRUPT.h in GSM.C and in main.c files.

The remedy, you suggested didnt work. :(

Since, Those variables are actually declared to hold the RCREG data i.e. data received from GSM modem, they must be in INTERRUPT.h without extern.
Code:
  uint8_t  G_ui8_RxBufCnt;
  uint8_t  G_ui8_RecvBuf[100];

The other files like GSM.c and main.c would be using those variables for analysis of the msg received. And hence I made them external in those files. I am not very confident about extern but I think, extern(in this case) would just suggest linker to use those variables in GSM.c and main.c taken from INTERRUPT.c (Please correct me, if I am wrong.)
 

uint8_t G_ui8_RxBufCnt;
uint8_t G_ui8_RecvBuf[100];
... to sum it all up, put the above snippet of variable declaration in "interrupt.c" and declare them extern to the other modules (gsm and main) by including "interrupt.h" containing the extern declaration.
 
Last edited:
@Arthur...
Thank you for the invaluable guidance. I got to learn 1 more imp rule of programming from you today. :)

I have already done this part...
Code:
#ifndef _INTERRUPT_h
#define _INTERRUPT_h

//variable declaration

#endif

This is what I did with my project...
Code:
#ifndef _GSM_H
#define _GSM_H


//****************************************
// Global Variable Declaration
//****************************************
extern	uint8_t	G_ui8_RxBufCnt;
extern	uint8_t	G_ui8_RecvBuf[100];


#endif

Code:
#include "StdTypes.h"

#ifndef _INTERRUPT_H
#define _INTERRUPT_H

uint8_t	G_ui8_RxBufCnt		=	0;
uint8_t	G_ui8_RecvBuf[100]	=	{" "};

void CHEK_isr_High	(void);
void CHEK_isr_Low	(void);
void RC_isr			(void);

#endif


Code:
#ifndef _MAIN_H
#define _MAIN_H

extern	uint8_t	G_ui8_RxBufCnt;
extern	uint8_t	G_ui8_RecvBuf[100];

extern	void UART_INIT(void);

#endif
 

This structure looks good to me.
Note that you don't need to put the keyword extern before function prototypes (but it's not an error to do it either).
Oh, and put your "multiple-inlcusion-prevention-definition" as the very first thing in your header files (even before #include "StdTypes.h")!

Otherwise, I'm glad I could help.
 
in main.h you don't need the extern declarations you can

Code:
#ifndef _MAIN_H
#define _MAIN_H

#include "gsm.h"

extern	void UART_INIT(void);

#endif
the advantage being if you need to change something, e.g. the size of G_ui8_RecvBuf[], you only need to edit gsm.h and gsm.c
 
I removed all #include INTERRUPT.h from main.c and GSM.c ...and it started working.
 

I removed all #include INTERRUPT.h from main.c and GSM.c ...and it started working.
That's not a good solution (even though it works). Please, read the posts above again and notice how I told you to declare and initialize your variables in "interrupt.c", then declare them as extern in "interrupt.h" (and only there!), which you're then free to include it wherever necessary.
Refer again to this post where I even highlighted the important statement.
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top