| Author |
Message |
|
|
Posted: Jul 15, 2007 - 05:42 PM |
|


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  |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Jul 19, 2007 - 01:53 PM |
|

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. |
|
|
| |
|
|
|
|
|
Posted: Jul 19, 2007 - 02:06 PM |
|


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 |
_________________
|
| |
|
|
|
|
|
Posted: Aug 13, 2007 - 07:31 PM |
|


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, |
|
|
| |
|
|
|
|
|
Posted: Aug 13, 2007 - 11:39 PM |
|


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  |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Aug 14, 2007 - 09:28 AM |
|


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 |
|
|
| |
|
|
|
|
|
Posted: Sep 21, 2007 - 11:05 AM |
|

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?  |
|
|
| |
|
|
|
|
|
Posted: Sep 21, 2007 - 11:22 AM |
|

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
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. |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2008 - 10:15 AM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2008 - 11:00 AM |
|


Joined: Jan 23, 2004
Posts: 9888
Location: Trondheim, Norway
|
|
You can do whatever you like and I can't do anything to stop you .
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  |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Mar 30, 2008 - 12:35 PM |
|


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. |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2008 - 12:56 PM |
|


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 |
_________________
|
| |
|
|
|
|
|
Posted: May 05, 2008 - 05:19 PM |
|


Joined: Apr 27, 2006
Posts: 257
Location: San Jose, CA
|
|
Awesome tutorial. Just what the doctor ordered.
Thanks Dean. |
|
|
| |
|
|
|
|
|
Posted: Aug 25, 2008 - 01:01 PM |
|

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
Thanks! |
|
|
| |
|
|
|
|
|
Posted: Aug 25, 2008 - 01:21 PM |
|

Joined: Sep 03, 2005
Posts: 795
Location: Christchurch, NZ
|
|
| You've got distance_measure.h included in ISR.c? |
|
|
| |
|
|
|
|
|
Posted: Aug 25, 2008 - 06:48 PM |
|


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. |
|
|
| |
|
|
|
|
|
Posted: Aug 25, 2008 - 07:58 PM |
|


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. |
|
|
| |
|
|
|
|
|
Posted: Aug 26, 2008 - 01:12 PM |
|

Joined: Aug 25, 2008
Posts: 6
Location: Wollongong, Australia
|
|
Thanks JohanEkdahl and davef for your replies.
However, now I have another problem.
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. |
|
|
| |
|
|
|
|
|
Posted: Aug 26, 2008 - 01:24 PM |
|


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. |
|
|
| |
|
|
|
|
|
Posted: Aug 26, 2008 - 01:25 PM |
|

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) |
|
|
| |
|
|
|
|
|