10 Replies Latest reply on Aug 28, 2016 3:50 PM by nathanael.esnault_1596721

    Multiple definition of variable.

    nathanael.esnault_1596721

      Hi everyone,

         

      I am using a PSOC5LP, CY8C5888LTI-LP for a project in which a RC boat is controlled w/ GPS and IMU.

         

      To clean up my code I created 5 header files associated w/ 5 code files : 

         

      Global, Autopilot, ToMatlab, IMU and GPS.

         

      Before I decided to clean up, everything was compiling without error. 

         

      And Now Psoc creator (V3.3) is throwing me 12 errors (all located in Global.c). The weird thing is when I click on the errors, it send me to some lines on the code where the variable is not even present.

         

      I tried to clean up but when I build again, Psoc creator throw me the same errors.

         

      I would really appreciate your help. I put a workspace bundle in the attachment. Thanks.

        • 1. Re: Multiple definition of variable.
          user_78878863

          Did you do a clean build?

             

          One thing that one should do with all header files to to wrap their content in an IFNDEF block like:

             

          #IFNDEF __NAME_H__

             

          #DEFINE __NAME_H__

             

          content...

             

          #ENDIF

             

          to ensure that the code is only included once.

             

          Then you can include the header files that you really need directly in the C files that need them (e.g. global.c should include project.h, global.h, gps.h and so on.

          • 2. Re: Multiple definition of variable.
            nathanael.esnault_1596721

            Thank you very much for your tip. I'll do it right now.

               

            And yes, I did  a "clean project" before trying  to compile it again. Is this what you are referring to ?

            • 3. Re: Multiple definition of variable.
              user_78878863

              Yes, either do a separate 'clean project' before 'build' or just 'clean and build'.

              • 4. Re: Multiple definition of variable.
                nathanael.esnault_1596721

                Thank for your answer but it didn't work. I got the same errors, even after I did a clean project and a build. But my code is more clean with the wrapper though.

                   

                Edit : I tried to use "external" on some variables but it didn't work.

                   

                It put all the code back in 1 file (the main) and it was working perfectly. I guess I'll stick to that.

                • 5. Re: Multiple definition of variable.
                  user_1377889

                  There are a few rules to follow when building C modules which consist of corresponding .c and .h files.

                     

                  Despite the required #ifndef ... mimic:

                     

                  Do not define any variables or functions in a .h file, declarations only. So no ram/flash gets allocated with a .h file.

                     

                  Always #include the .h file in the corresponding .c

                     

                  Variables that need to be accessed from outside the module should be defined in the .h as extern and are declared in the .c

                     

                  Global variables and functions in the .c file that are not accessed from outside should be declared as "static".

                     

                  Advantages are quite obvious: You can pick a module and re-use the original code in a different project without modifications, so no need for a cut & paste which makes updating/correcting difficult (In which projects did I use that module???)

                     

                   

                     

                  To make things more clear:

                     

                  uint8 Myfunc(void);    //  This is a definition, a function prototype

                     

                  double f;   //  This is a declaration. Allocates memory for f

                     

                  extern int Counter;    //  This is a definition. Just tells the compiler that there is a variable anywhere

                     

                  float Square(float x)    //  This is a declaration. The fuction will occupy some flash
                      return x * x;
                  }

                     

                   

                     

                  Happy coding.

                     

                  Bob

                  • 6. Re: Multiple definition of variable.
                    nathanael.esnault_1596721

                    Thank you very much for your reply Bob. I will apply your rules. I managed to create some header files with only struct definition and the define (no variables or function definition). I made less header files though. Will it be interesting if I put a bundle of my new version  in attachment ?

                    • 7. Re: Multiple definition of variable.
                      user_1377889

                      Will it be interesting if I put a bundle of my new version  in attachment ? Yes, of course. I'll have a look into. But be warned: I usually focus on readability and safety of program code.

                         

                       

                         

                      Bob

                      • 8. Re: Multiple definition of variable.
                        nathanael.esnault_1596721

                        Ok here is my bundle.

                           

                        I just want to warn you that I put my global variables in a header file GVL.h temporary so my main code could be a little less messy.

                           

                        I do got errors on the file but once compiled, everything works ok. Once the project will reach the end I will put the  global variables back in the main.

                        • 9. Re: Multiple definition of variable.
                          user_1377889

                          As you can see by yourself: your project is rather difficult to read due to poor modularisation. When searching for a function or functionality it is not easy to get to the correct point. As I said, make definitions for modules (matlab is a good example) and create a .h and a .c file offering only the required functions.

                             

                                  if (strcmp(&Direction,"S"))//Starboard
                          This is an error!!! Direction is declared as a character, correct to

                             

                                  if (Direction =='S'))//Starboard

                             

                          There are some more of those, check that.

                             

                                      L3GD20_ReadGyro(&gyroData);
                          is flagged with a warning!

                             

                          gyroData is a Vector3 *, so you are trying to take the address of a pointer. Not good... use

                             

                                      L3GD20_ReadGyro(gyroData);

                             

                          As a tip: divide et impera! Take small steps to modularisation, not all at once.

                             

                          Variables accessed in main() only do not have to be defined as global. Define them as static in main(), that will preserve stack and helps modularisation. Example:   
                          TimerPeriod = Timer_MATLAB_ReadPeriod();

                             

                          Take care with a late (too late) CYGlobalIntEnable. there are some components that require interrupt enabled at initialization.

                             

                          I always suggest to create a InitializeSystem() function. This shortens main().

                             

                          All settings and #defines that are project specific go into a separate .h file. Imagine, you use that very same project with a different boat with different motors and different IMU devices, what (and where) do you have to apply changes?

                             

                          1 big file (as it is now)
                          several smaller files (where you can easily get to)
                          one small file (which would be best)

                             

                          When you are building a work that should be judged by somebody else, how will he (or she) do that? Runs -doesn't run basis? Or will there be a closer look at (into) the sources? What will be the first thing to look at? The answer is: main() so try to make it easy to find, easy to read and very easy to understand!! Take out small functions to describe what you want to do as:

                             

                                              GPS.DGPS_mess_available = 0;
                                              GPS.DGPS_Corr_Long  = 0;
                                              GPS.DGPS_Corr_Lat   = 0;
                                              GPS.DGPS_Corr_Alt   = 0;
                          This could be shortened to
                                             ZeroGPS();

                             

                           

                             

                          Well, enough of hints and advices, happy coding!

                             

                          Bob

                          • 10. Re: Multiple definition of variable.
                            nathanael.esnault_1596721

                            Thank you very much for your detailed  answer and your time. I will correct the errors as soon as I can. If you are around Auckland one day I'll buy you a drink ;) !  Code, here I come !