Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
abcminiuser
PostPosted: Jul 15, 2007 - 05:42 PM
Moderator


Joined: Jan 23, 2004
Posts: 9888
Location: Trondheim, Norway

Yes, the "right" way is to include all the required header files. If you've structured your project as this tutorial teaches, including the header files should do nothing more than expose typedefs, enums, macros, prototypes and variable declarations - no code size penalty. If you *really* want, you can make public and private headers for each file, with only the items that need to be globally exposed in the public headers.

- Dean Twisted Evil

_________________
Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
mrono
PostPosted: Jul 19, 2007 - 01:53 PM
Wannabe


Joined: Jan 04, 2006
Posts: 87


Quote:

If you *really* want, you can make public and private headers for each file, with only the items that need to be globally exposed in the public headers.

I've sometimes wondered if I should be doing this. But how would one keep the private header private? Simply not mention it in documentation? Or add a big comment "Should only be included in foo.c"? Splitting things that are only needed in one file to another file 'feels' wrong even though it would follow the rule that declarations go to header files.

So I usually put declarations of static functions and constants only needed in one place to the top of the corresponding .c file. I would appreciate any advice or comments others may have on this.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 19, 2007 - 02:06 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62944
Location: (using avr-gcc in) Finchingfield, Essex, England

In our large projects a module will generally have a three letter acronym (e.g. SPI) and in the \spi directory there will be various spi???.c files, an spi.h that is the "public" header file that may be #include'd by other modules or main code in the project then any .h stuff that other modules don't need to see will go into spii.h (the added i for "internal"). While the tla???.c files will probably include tla.h and tlai.h, outside of that directory the C files will only include tla.h (they may know that tlai.h exists but would never use it directly)

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Go4it
PostPosted: Aug 13, 2007 - 07:31 PM
Hangaround


Joined: Jun 28, 2004
Posts: 110
Location: Belgium

Hi All,
Again a great tutorial here.
Where should I best store these new source and header files in Winavr ?
Where to configure the path to these files ?
Do I have to configere the path ones ?
Or do I have to add Header and Source files in the left
column named "AVR GCC" in AvrStudio for each new project that needs these files ?
Thanks,
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
abcminiuser
PostPosted: Aug 13, 2007 - 11:39 PM
Moderator


Joined: Jan 23, 2004
Posts: 9888
Location: Trondheim, Norway

Hi Go4It,

Thanks for the compliment.

Quote:
Where should I best store these new source and header files in Winavr ?
Where to configure the path to these files ?
Do I have to configere the path ones ?
Or do I have to add Header and Source files in the left
column named "AVR GCC" in AvrStudio for each new project that needs these files ?


I don't have much experience in using AVRStudio as a GCC frontend, so the following is only what I believe to be the case. I'm sure someone else will correct me if I get things wrong.

You should put your source files in the same directory as your main project source file, to keep things neat and ordered. You should then add them to the left AVRStudio source file pane, to tell AVRStudio to compile and link them in with your main source file.

- Dean Twisted Evil

_________________
Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
ikletti
PostPosted: Aug 14, 2007 - 09:28 AM
Hangaround


Joined: Oct 17, 2003
Posts: 311
Location: Germany

abcminiuser wrote:

Quote:
Where should I best store these new source and header files in Winavr ?
Where to configure the path to these files ?
Do I have to configere the path ones ?
Or do I have to add Header and Source files in the left
column named "AVR GCC" in AvrStudio for each new project that needs these files ?


[...]You should put your source files in the same directory as your main project source file, to keep things neat and ordered. You should then add them to the left AVRStudio source file pane, to tell AVRStudio to compile and link them in with your main source file.

Right click on 'Source files' -> 'Add existing source file(s)' to do this and add all .c files.

Then add the #include statements for the corresponding .h files on the top of your main source file.

Ingo
 
 View user's profile Send private message  
Reply with quote Back to top
farlane
PostPosted: Sep 21, 2007 - 11:05 AM
Newbie


Joined: Sep 21, 2007
Posts: 2


clawson wrote:
Dean,

Our coding standard contains an extension of your function naming suggestion that others may find useful. Here's an excerpt from our standard:

http://www.ourcottage.plus.com/cs.html



quote from your link:

Quote:

Note: C doesn’t support the concept of a module global, this naming convention allows the
distinction between a system global which would be used by other modules from a module
global which should not be accessed by other modules


Isnt it so that making a module level variable static means its global to module level and inaccessible from other modules?

For that matter, not declaring the variable in the modules header file will generate an 'undeclared ...' warning when it is used from outside the module. And we always want zero warnings right? Smile
 
 View user's profile Send private message  
Reply with quote Back to top
farlane
PostPosted: Sep 21, 2007 - 11:22 AM
Newbie


Joined: Sep 21, 2007
Posts: 2


abcminiuser wrote:
If you *really* want, you can make public and private headers for each file, with only the items that need to be globally exposed in the public headers.

- Dean Twisted Evil


Private declarations belong in the source file itself, not in a header. This is the only way of ensuring that no other module knows about the private declarations.
 
 View user's profile Send private message  
Reply with quote Back to top
mrx23dot
PostPosted: Mar 30, 2008 - 10:15 AM
Wannabe


Joined: Jun 29, 2007
Posts: 75


Hi!

Can I make one big Common.h for all .c files?
Common.h would contain:

-#include <io.h>
-all function's prototype,
-extern.. global vars (these are defined in the beginning of main.c)

Common.h would be included in every *.c file in the project.
So there will be multiple prototypes, global var declarations.
But is this a problem?

Thx
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Mar 30, 2008 - 11:00 AM
Moderator


Joined: Jan 23, 2004
Posts: 9888
Location: Trondheim, Norway

You can do whatever you like and I can't do anything to stop you Wink.

However, I'd recommend against it. Generally, it's considered good practice to go with the normal one header per source file route. That way each source file only includes what is needed, preventing multiple definition problems and speeding up compilation.

- Dean Twisted Evil

_________________
Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: Mar 30, 2008 - 12:35 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

mrx23dot wrote:

But is this a problem?


Dean wrote:

[...]go with the normal one header per source file route. That way each source file only includes what is needed, preventing multiple definition problems and speeding up compilation.


And apart fromthose two (valid) points, ponder this: What happends when you want to take one piece of the developed source code and use in another project. Example: Some code to handle a "ring buffer" "on top" of the UART, or maybe some code to handle a LCD display. If all your prototypes are in one big header file you now have to copy the parts you want and paste them into another header file for the new project. If you had a separate RingBuffer.h or LCD.h (to accompany your RingBuffer.c or LCD.c) you'd just make a copy of the files to the new project.

And after doing that for a while you get problems with those copies drifting apart leading to eg. bugs fixed in one project being un-fixed in another. You realise that you need those files stored in one master place. Every time you fix a bug or make an enhancement you'd update the master files, test them and then distribute them to all projects that are using them.

(And after doing that for a while you'd stop distributing the sources to the different projects and instead build librarys of precompiled code to distribute. Or you might set up your own version control system, eg. Subversion and store the files there...)

Anyhow, my point is - it's not only about compiler efficiency and avoiding build errors. Its just as much about making code reuse easy, efficient and less error-prone.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Mar 30, 2008 - 12:56 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62944
Location: (using avr-gcc in) Finchingfield, Essex, England

I don't have a .h file for every .c file but one .h file for every "module" that may actually contain a number of .c files. So I might have ADC support in a single adc.c with a corresponding adc.h but for something like a flash filing system there could be 10 or more .c files and a single ffs.h

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
dpaulsen
PostPosted: May 05, 2008 - 05:19 PM
Hangaround


Joined: Apr 27, 2006
Posts: 257
Location: San Jose, CA

Awesome tutorial. Just what the doctor ordered.

Thanks Dean.
 
 View user's profile Send private message  
Reply with quote Back to top
volatile_AH
PostPosted: Aug 25, 2008 - 01:01 PM
Newbie


Joined: Aug 25, 2008
Posts: 6
Location: Wollongong, Australia

Guys,

I've been working on a project for uni and have been putting all my code into the one .c file and the one .h file.

However, it was all getting a bit messy, so I decided to try and break it all up into seperate .c and .h files for ease of documentation.

However, I'm now getting an issue when I try and compile.
I get messages such as

Code:
../ISR.c:13: In function '__vector_6':
../ISR.c:31: error: 'distance_string' undeclared (first use in this function)


'distance_string' is declared in another header file (distance_measure.h) with the 'extern' keyword, so I don't understand why AVR Studio isn't linking it correctly. Do I have to include distance_measure.h in isr.h? Through reading Dean's tutorial it makes it sound like I only do this if I am calling a function from another file.

Can anyone help me out with some ideas to try?
If I need to post the code I will, it's just that it's all a bit messy at the moment Wink

Thanks!
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Aug 25, 2008 - 01:21 PM
Resident


Joined: Sep 03, 2005
Posts: 795
Location: Christchurch, NZ

You've got distance_measure.h included in ISR.c?
 
 View user's profile Send private message  
Reply with quote Back to top
dpaulsen
PostPosted: Aug 25, 2008 - 06:48 PM
Hangaround


Joined: Apr 27, 2006
Posts: 257
Location: San Jose, CA

I would like to add a tip that will save you a lot of time in Programmers Notepad. There is an easy way to prepend extern to long lists of declarations:

1)Make a vertical list of the word "extern " (note the space character) on the left margin using copy and paste
2)Hold down the Alt key and click and drag a box around the list you just made. The list should be selected now.
3)Cut
4)Place the cursor at the beginning of the list of declarations
5)Paste

If you do this, PN should have prepended your declarations with "extern ". I hope this is helpful to someone.

edit: I just figured out that it works in AVR Studio also, only you have to continue holding Alt until after you cut. And also you have to issue the cut command with the mouse not the keyboard.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Aug 25, 2008 - 07:58 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

Quote:

Do I have to include distance_measure.h in isr.h?

Include it in isr.c, as hinted at by davef.

We see questions similar to this on and off here at 'freaks, and what you really need to know to analyze the situation yourself (rather than us just giving a cook-book recipe for resolving it) is that all includes are handled by the preprocessor before the compiler proper starts looking at the source. Wherever an #include is done, in that place the whole header file is inserted into the source code (and nested includes work that way too). So when the compiler proper starts working there are no #includes left in the "compilation unit".

Now, in your ISR.c, on line 31, the declaration of distance_string must aready have been seen by the compiler.

If you are really curious there is a switch to the gcc compiler to produce a listing file which shows what the compiler proper sees after the preprocessor has "mangled" the file. I don't recall the syntax of the switch - go to the (avr-)gcc documentation if you really want to try it out.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
volatile_AH
PostPosted: Aug 26, 2008 - 01:12 PM
Newbie


Joined: Aug 25, 2008
Posts: 6
Location: Wollongong, Australia

Thanks JohanEkdahl and davef for your replies.

However, now I have another problem. Sad

I started getting alot more error messages saying things like:

Code:
ISR.c: (.text+0x1a): undefined reference to 'distance_string'


and for other global variables.

I went and removed the 'extern' keyword from all the global variables declared in the different header files just to see what happened, and the error messages changed to

Code:
 ... multiple definition of...


Now I don't know why this is occurring either, because the variables are only declared in ONE header file, and I have put

Code:
 #ifndef DISTANCE_MEASURE_H
#define DISTANCE_MEASURE_H
...
#endif


in each of the header files.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Aug 26, 2008 - 01:24 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18757
Location: Lund, Sweden

The "undefined reference to X" is probably because the source file that actually defines (implements) X is not included in the project. While compiling, the compiler only sees

extern type X

and goes "Oh, allright it is somewhere, but I don't know where. Another instance of me the compiler will see it while compiling some other source file, and we both will leave it to the linker to resolve this." As that other file never is compiled the linker will not see it and goes "Darn, here's a reference that I cannot resolve".

When you remove all those extern from the declarations they all turn into definitions (implementations) of X. Now every time the compiler sees one of those it will emit code for it into the object file. And when the linker gets hold a hold of thyose object files it has to emit an error becuse it sees the same variable implemented several times.

The solution to the first problem is not to delete all "extern" thingies, but to locate the source file that actually implements X and see to it that it gets compiled and linked in.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
volatile_AH
PostPosted: Aug 26, 2008 - 01:25 PM
Newbie


Joined: Aug 25, 2008
Posts: 6
Location: Wollongong, Australia

Sorry when I say I've put
Code:
#ifndef DISTANCE_MEASURE_H
...


I mean I've named them differently depending on the name of the header file (eg. ISR_H for isr.h, etc etc etc)
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits