I have used this tutorial as a basis for splitting up my code for larger projects, however my compiler (GCC) is grumpy and coming up with the following warnings regarding the static function declarations:
Quote:
../SDCard.h:108: warning: 'SendCommand_SDC' declared 'static' but never defined
The function definition is definitely in the .c file with a declaration in the .h file.
If need be I can include the full code, however I get this with all of my static functions and do not think it is necessary.
Does anyone know what this warning is about? I have searched for a list of warnings, but have had little success. I obviously prefer to not have any warnings, even if they are not hazardous to the codes execution.
I would like to find out more about the compiler warnings, for future reference, as in a complete list of warnings and there meanings. As well as a work around for this problem.
Posted by JohanEkdahl: Fri. Jul 31, 2009 - 07:57 AM
1
2
3
4
5
Total votes: 0
I suppose you are including the header file into more than one source file, but only define (implement) the static function in one of them.
If the function is static, this means that it is only visible inside the source file where it is defined, and thus it's function prototype needs not be in the header file at all. For me the primary reason for header files is tha they are "contracts" between proucers and consumers of eg functions. In your case the producer and the consumer is the same source file, so the contract can be in that file itself.
You can of-course place such a prototype in a header file, but you will need a separate such heaer file for each source file that declares static functions.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
What we do for any given module TLA is to have both a tla.h which is Johan's public "contract" and also a tlai.h (i=internal) which is a private header file for information that only needs to be used amongst the components of the module. However we wouldn't put a static function declaration into even the tlai.h. The thole point of "static" is that they are private to the one .c file where they are defined so if the function needs to be announced before it is used a simple declaration would be made within the early sections of the .c
spliting is very nice idea, as one said you'll especially benefit when using OO languages. The disadvantage is that with separate compilations compiler has much less oportunities to optimize program. For example (AFAIK) it doesn't inline code compiled in other module, it pushes more registers then needed or just leaves unused functions in generated header. Therefore after such spliting user usually should be more compilator-aware - for example ISR that call function should be in same module - function we'll be inlined, or at least only needed registers we'll go to the stack.
This is the makefile I'm using with CrossPack for OS X:
# Name: Makefile
# Author:
# Copyright:
# License:
# This is a prototype Makefile. Modify it according to your needs.
# You should at least check the settings for
# DEVICE ....... The AVR device you compile for
# CLOCK ........ Target AVR clock rate in Hertz
# OBJECTS ...... The object files created from your source files. This list is
# usually the same as the list of source files with suffix ".o".
# PROGRAMMER ... Options to avrdude which define the hardware you use for
# uploading to the AVR and the interface where this hardware
# is connected.
# FUSES ........ Parameters for avrdude to flash the fuses appropriately.
DEVICE = atmega8
CLOCK = 8000000
PROGRAMMER = -c stk500v2 -P /dev/tty.usbserial-A3000HDB
OBJECTS = main.o
FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m
# ATMega8 fuse bits (fuse bits for other devices are different!):
# Example for 8 MHz internal oscillator
# Fuse high byte:
# 0xd9 = 1 1 0 1 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000)
# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0
# | | | | | +-------- BOOTSZ1
# | | | | +---------- EESAVE (set to 0 to preserve EEPROM over chip erase)
# | | | +-------------- CKOPT (clock option, depends on oscillator type)
# | | +---------------- SPIEN (if set to 1, serial programming is disabled)
# | +------------------ WDTON (if set to 0, watchdog is always on)
# +-------------------- RSTDISBL (if set to 0, RESET pin is disabled)
# Fuse low byte:
# 0x24 = 0 0 1 0 0 1 0 0
# ^ ^ \ / \--+--/
# | | | +------- CKSEL 3..0 (8M internal RC)
# | | +--------------- SUT 1..0 (slowly rising power)
# | +------------------ BODEN (if 0, brown-out detector is enabled)
# +-------------------- BODLEVEL (if 0: 4V, if 1: 2.7V)
# Example for 12 MHz external crystal:
# Fuse high byte:
# 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000)
# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0
# | | | | | +-------- BOOTSZ1
# | | | | +---------- EESAVE (set to 0 to preserve EEPROM over chip erase)
# | | | +-------------- CKOPT (clock option, depends on oscillator type)
# | | +---------------- SPIEN (if set to 1, serial programming is disabled)
# | +------------------ WDTON (if set to 0, watchdog is always on)
# +-------------------- RSTDISBL (if set to 0, RESET pin is disabled)
# Fuse low byte:
# 0x9f = 1 0 0 1 1 1 1 1
# ^ ^ \ / \--+--/
# | | | +------- CKSEL 3..0 (external >8M crystal)
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled)
# | +------------------ BODEN (if 0, brown-out detector is enabled)
# +-------------------- BODLEVEL (if 0: 4V, if 1: 2.7V)
# Tune the lines below only if you know what you are doing:
AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE)
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)
# symbolic targets:
all: main.hex
.c.o:
$(COMPILE) -c $< -o $@
.S.o:
$(COMPILE) -x assembler-with-cpp -c $< -o $@
# "-x assembler-with-cpp" should not be necessary since this is the default
# file type for the .S (with capital S) extension. However, upper case
# characters are not always preserved on Windows. To ensure WinAVR
# compatibility define the file type manually.
.c.s:
$(COMPILE) -S $< -o $@
flash: all
$(AVRDUDE) -U flash:w:main.hex:i
fuse:
$(AVRDUDE) $(FUSES)
# Xcode uses the Makefile targets "", "clean" and "install"
install: flash fuse
# if you use a bootloader, change the command below appropriately:
load: all
bootloadHID main.hex
clean:
rm -f main.hex main.elf $(OBJECTS)
# file targets:
main.elf: $(OBJECTS)
$(COMPILE) -o main.elf $(OBJECTS)
main.hex: main.elf
rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
# If you have an EEPROM section, you must also create a hex file for the
# EEPROM and add it to the "flash" target.
# Targets for code debugging and analysis:
disasm: main.elf
avr-objdump -d main.elf
cpp:
$(COMPILE) -E main.c
How can I edit this to allow adding additional .c files? Right now, I have to do #include "uart.c" to get it to work; which simply embeds said code in main.c rather than having the compiler link it in.
Tried to see if the makefile could first make uart.o from uart.c and then link uart.o and main.o to yield main.hex; not making much progress in this as aspect though.
Posted by JohanEkdahl: Wed. Sep 9, 2009 - 09:56 PM
1
2
3
4
5
Total votes: 0
The clue seems to be here
Quote:
# OBJECTS ...... The object files created from your source files. This list is
# usually the same as the list of source files with suffix ".o".
It's late, so I wont test it but you could try to add the names of other object to be built to this variable. Eg if your project consists of main.c and uart.c then
OBJECTS = main.o uart.o
You will of-course also have to edit up a uart.h with the things (eg function prototypes, extern declarations of "shared" variables etc) that needs to be seen from both main.c and uart.c and #include that file in both main.c and uart.c .
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
You will of-course also have to edit up a uart.h with the things (eg function prototypes, extern declarations of "shared" variables etc) that needs to be seen from both main.c and uart.c and #include that file in both main.c and uart.c .
Thanks Johan! I did try having uart.o in the OBJECT definition but I was getting this strange error:
Personally, when there's a lot of common system headers included in each .c I'd put the #includes in a syshdr.h and then just #include "syshdr.h" in each .c to reduce the "noise". On the occasion that the interrupt header file changes from to I'd then just need to make the change in one place - not edit every .c where it is included.
Personally, when there's a lot of common system headers included in each .c I'd put the #includes in a syshdr.h and then just #include "syshdr.h" in each .c to reduce the "noise".
You might want to rename it to syshdr.inc, perhaps, to stress the fact that it is *not* a *header* (i.e. "interface description of a *.c") as such.
Posted by JohanEkdahl: Thu. Sep 10, 2009 - 02:11 PM
1
2
3
4
5
Total votes: 0
Quote:
You might want to rename it to syshdr.inc, perhaps, to stress the fact that it is *not* a *header* (i.e. "interface description of a *.c") as such.
Perhaps. Perhaps not. The use of ".h" as the extension even for nested includes is quite wide-spread.
AFAICR this is the first time I see the notion of making the super-include-files have a filetype of ".inc". Is this a cultural thing, where eg U*ix people do it, and others (eg MS) don't?
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
In our coding standard it would most definitely be a .h, we do have the concept of ".i" to but that's for the very specific purpose of a block of externally generated const data that MUST only be #include'd in one .c file - the .i rather than .h makes this clear to the casual reader.
Personally, when there's a lot of common system headers included in each .c I'd put the #includes in a syshdr.h and then just #include "syshdr.h" in each .c to reduce the "noise".
You might want to rename it to syshdr.inc, perhaps, to stress the fact that it is *not* a *header* (i.e. "interface description of a *.c") as such.
JW
During my C/C++ classes at Uni and even most books I have always seen the use of ".h" and never the use of ".inc".
Posted by abcminiuser: Thu. Sep 10, 2009 - 11:21 PM
1
2
3
4
5
Total votes: 0
Quote:
During my C/C++ classes at Uni and even most books I have always seen the use of ".h" and never the use of ".inc".
Doesn't matter what extension you use on a file #include'd in your code -- the preprocessor will process it just the same. That said, personally I think it extremely poor form to use anything other than the .h unless it's something very unusual, like a giant array of PCM audio data which needs to be embedded. Even then, I'd make the embedding of resource files a compile step, and not part of the actual code.
Each to his own, but don't be surprised if you get fired for naming all your C header files "Includes.jpg".
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
You might want to rename it to syshdr.inc, perhaps, to stress the fact that it is *not* a *header* (i.e. "interface description of a *.c") as such.
Perhaps. Perhaps not. The use of ".h" as the extension even for nested includes is quite wide-spread.
AFAICR this is the first time I see the notion of making the super-include-files have a filetype of ".inc". Is this a cultural thing, where eg U*ix people do it, and others (eg MS) don't?
It most definitely isn't a *nix thing. A quick journey through the system headers in a linux install will reveal that many are simply includes of other headers, usually architecture specific. I too have never seen the suggestion to use an extension other than .h for this purpose. Just because a file is used to consolidate common includes, does not make it "not a header".
.inc from my experience is usually reserved for includes in assembly projects.
But as Dean stated, the C compiler does not care what the extension is. #include is simply a text insertion.
Writing code is like having sex.... make one little mistake, and you're supporting it for life.
The use of ".h" as the extension even for nested includes is quite wide-spread.
A poor practice, however widespread, is still a poor practice. Replace "sub-optimal" for "poor" in the above if you find it offensive.
glitch wrote:
.inc from my experience is usually reserved for includes in assembly projects.
The choice of extension is arbitrary, but I agree that defacto standards have to be respected. As you might have noticed, I don't have that much of an experience with projects invoving C (I try to avoid them, in fact, being a dedicated C-hater ;-) ). Any other extension would do - fancy .hh?
glitch wrote:
But as Dean stated, the C compiler does not care what the extension is. #include is simply a text insertion.
And that's the problem. The C/*nix folks are not known for being meticulous to the detail, are they. And, if they have chance to take a shortcut, they take it. So it's upon the poor programmer to maintain a discipline, so that the gun won't fire in the direction of the toes.
While it's very easy to implement literal inclusion, it's hard to do it in the proper way. So there's no enforcement of binding the header to the actual source, nor of rejecting irrelevant information from it. There is no syntactical distinction between "include your own header for making sure it matches the body of module", "include a header of the module to be able to link to its functions and variables", and "include an arbitrary text - possibly a collection of headers".
And this is why it is hard to explain to the novices the concept of headers. This thread is in a tutorial section after all, isn't it.
Even \Program Files\Microsoft Visual Studio\VC98\include\windows.h is little more than a bunch of #include's
And, as has already been stated, the technique is used a LOT in the Linux kernel tree.
It may not be "good practice" but it's what C programmers have actually been doing in large projects since time immemorial. In fact that includes me in large in-house projects (one with 57,000 .c files) - some are "meta headers" that just group the inclusion of a bunch of other headers.
Well, that might be a collection, but of what are not headers either. I would assign them a .def :-) OK, this is stretching the things a bit further than you traditionalists would be willing to accept... :-)
clawson wrote:
Even \Program Files\Microsoft Visual Studio\VC98\include\windows.h is little more than a bunch of #include's
Oh, are you trying to tell us that M$ sets the benchmark in good programming practices? :-P
Oh, are you trying to tell us that M$ sets the benchmark in good programming practices?
Well, yes, actually I do believe that. While people decry Microsoft their own source code is very good quality. The reason people call Windows "buggy" is that it does not isolate driver code enough and when Tom, Dick or Harry get a copy of the DDK and write their own webcam or scanner driver it has the ability to crash the kernel (in fact the same is true of anything that is insmod/modprobe'd into the Linux kernel too). The end user's experience is that "Windows has crashed" but more often than not it's 3rd party driver code that has crashed.
In fact a lot of the coding standard we adhere too is based on the writings of Steve Maguire in Writing Solid Code:
He outlines the techniques that Microsoft use internally to avoid the more obvious code faults. If you like it's a bit like a cut-down, less stringent MISRA rule book. That is a very very good book and I highly recommend it to anyone programming in C. While I've had office "purges" over the years and had to discard a lot of books to make room, this remains one of the core books (like K&R, the Borland C reference and Charles Petzold on programming Windows) that I'll retain for all time.
I have never seen anyone who uses a .inc extension for included files in C. In fact, the only variation I have ever really seen other than .h is to use no extension at all (an older practice that has gone out of favor). So I'm not sure how you can say in one breath that you should follow the de facto standard, but in another say to throw the de facto standard out the window only to advocate something else that virtually no one else does.
So I'm not sure how you can say in one breath that you should follow the de facto standard, but in another say to throw the de facto standard out the window only to advocate something else that virtually no one else does.
Well, using an already "assigned" extension for a different purpose would cause confusion; while using an already "unassigned" extension for the non-interface headers would cause at worst a mild attention.
But of course there's no point to push it beyond reason. There are many controversial items in various coding standards to add one more. The thinking programmer develops his own little variations anyway.
I rest the case.
JW
PS. I googled for "file name extension .i" and learned that it is likely to be an INTERCALC file... :-P
There are many controversial items in various coding standards to add one more.
This is not a controversial item, you are just trying to make it into one, pulling arguments out of thin air.
You seriously underestimate the value of established conventions and traditions. The existence of a convention is a value as such, even if the convention is (in your imagination) not optimal. You forgot that there isn't black and white only, but that engineering is a string of compromises and most results are grey. You forgot that it is usually a huge waste of time and money to do things perfect (the 80/20 rule of thumb). Engineering is not about perfection.
You forgot that there isn't black and white only, but that engineering is a string of compromises and most results are grey. You forgot that it is usually a huge waste of time and money to do things perfect (the 80/20 rule of thumb). Engineering is not about perfection.
[wek, standing ashamed in the corner of the room, nodding quietly while concentrating on his yet unshot toes, letting out a sob now and then...]
Well, using an already "assigned" extension for a different purpose would cause confusion;
How is it a different purpose? #include is used to include other files, and that is what is being done. There is nothing in the designation ".h" that implies what the content of the file is other than that it is intended to be included by other files.
There is a simple cure for case problems: Don't Capitalize!
main(), printf(), int, static, avr/interrupt.h, _asm_, _delay_us... See the pattern? Just say no. And in case you feel like a JavaRebel, ok, but at least be consistent.
The exceptions are things already mentioned, constants, macros, classes, header top ifdef's. F_CPU, DEBUG, DDRA, //FIXME, M_PI, RAND_MAX...
A few outstanding conventions exist, like Makefile with a capital M so it stands out from code and README(.txt) in all caps because that's the first thing that should stand out at a glance.
There isn't one. But what's the problem? You take the Mfile template. Edit the names of all the C (.c) source files onto the SRC= line, the name of Asm (.S) source files into the ASRC= line and the name of all the C++ (.C) files onto the CPPSRC= line and that's it. Job done.
I have numbers of global variables in my projects. Is it possible to put all the global variables in one .h file and include this file in all the .c file ?
I am defining the global variables using extern word.
If I am doing this way then it is giving me error
"
(.text.avr-libc.fplib+0x0): multiple definition of `__floatunsisf'
"
I do this but not how you suggested. As this article hopefully explained there should never be any definitions in a .h file, only declarations. So create a new .c file called something like:
globals.c
int n;
char c;
long l;
and add it to the list of source files to be compiled. Then also create:
globals.h
extern int n;
extern char c;
extern long l;
and #include this in any file that needs access to 'n', 'c' or 'l'
In fact I often take this one stage further and group all the globals in a struct. So I have in the .h file:
Posted by JohanEkdahl: Sat. Nov 20, 2010 - 07:27 PM
1
2
3
4
5
Total votes: 0
Quote:
I have numbers of global variables in my projects. Is it possible to put all the global variables in one .h file and include this file in all the .c file ?
No, this will not work. As I'm sure has been explained earlier in this thread you will get duplicate definitions of those variables, and the linker generating errors.
What you should do has also most likely been described earlier in this thread:
- Place definitions of your global variables in one .c source file.
- Add that .c source file to the project so that it gets compiled.
- Put extern declarations of the ame variables in a .h header file.
- Include that .h header file into all .c source files that needs to see the variables.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
By the way I just looked back at your post and the __floatunsisf error is actually because you are using FP functions without linking with libm.a, nothing to do with your own variables (in the case of that particular error message)
By the way I just looked back at your post and the __floatunsisf error is actually because you are using FP functions without linking with libm.a, nothing to do with your own variables (in the case of that particular error message)
Could you please explain how to eliminate this error?
Posted by abcminiuser: Sun. Nov 21, 2010 - 02:13 AM
1
2
3
4
5
Total votes: 0
Quote:
I have numbers of global variables in my projects. Is it possible to put all the global variables in one .h file and include this file in all the .c file ?
Yes, you can have all your "extern" (publically visible) globals listed in one header file. However, you will still need to place them in one of your .c files as well without the "extern" modifier, otherwise you will receive undefined reference errors.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Posted by vijayrao1988: Sat. Jan 29, 2011 - 08:48 AM
1
2
3
4
5
Total votes: 0
I am trying to write a header file and put up everything related to TWI in it, leaving only the main processing to the main.c and functions being called as and when required. I want the TWI ISRs to be contained by this header. The program compiles fine, but somehow the ISR just isn't executing. Could you please help me out with this?
And, should I be using a .c file instead of the .h file.
Posted by abcminiuser: Sat. Jan 29, 2011 - 10:25 AM
1
2
3
4
5
Total votes: 0
An ISR is effectively just a fancy regular function - and anything that results in actual executable code in the binary should be a .c file rather than a .h file. Try creating a TWI.c and TWI.h pair, with the ISRs in the C file.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
Posted by JohanEkdahl: Sat. Jan 29, 2011 - 10:31 AM
1
2
3
4
5
Total votes: 0
Quote:
The program compiles fine, but somehow the ISR just isn't executing. Could you please advise me something on this?
The snide remark is that you are yet another one that has a problem on line 42 of your source code.
Seriously: We can't say much unless you post your code. It helps boost interest in helping you if you reduce the code to the smallest possible that still builds and executes and displays the problem.
Quote:
And, should I be using a .c file instead of the .h file.
The usual case is a .c file and a .h file. Go read the tutorial here on "Managing large projects".
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
Posted by JohanEkdahl: Sat. Jan 29, 2011 - 12:40 PM
1
2
3
4
5
Total votes: 0
Blimey! Didn't notice we where already there. :roll:
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
You Did not mention where to define ISR routines when splitting a large project into different .c and .h files. Is it in the same file where main() function defined?
One key thing is if the ISR() calls any functions then either make them static inline - in which case they could actually be located in a .h file - otherwise put them in the same .c file where the ISR() is located so the compiler has some chance of determining register usage and will not be forced to save/restore the entire context.
To add to what Dean says. A typedef does not create any storage. A definition of the array of struct does. The only things you want to avoid in a header file are anything that leads to storage being allocated. So it's the variable definition that needs to be turned into a declaration only. You do this by adding 'extern'.
Sorry if this was already asked.
Not explicitly said this tutorial seems to indicate that say "usart.h" does not need to include "usart.c" is that true?
Is agreeing with the positive comments on this thread
-Jd from the land of the Pacman
- Log in or register to post comments
TopHi there guys
I have used this tutorial as a basis for splitting up my code for larger projects, however my compiler (GCC) is grumpy and coming up with the following warnings regarding the static function declarations:
The function definition is definitely in the .c file with a declaration in the .h file.
If need be I can include the full code, however I get this with all of my static functions and do not think it is necessary.
Does anyone know what this warning is about? I have searched for a list of warnings, but have had little success. I obviously prefer to not have any warnings, even if they are not hazardous to the codes execution.
I would like to find out more about the compiler warnings, for future reference, as in a complete list of warnings and there meanings. As well as a work around for this problem.
Thank you in advance.
Regards,
Derek
- Log in or register to post comments
TopI suppose you are including the header file into more than one source file, but only define (implement) the static function in one of them.
If the function is static, this means that it is only visible inside the source file where it is defined, and thus it's function prototype needs not be in the header file at all. For me the primary reason for header files is tha they are "contracts" between proucers and consumers of eg functions. In your case the producer and the consumer is the same source file, so the contract can be in that file itself.
You can of-course place such a prototype in a header file, but you will need a separate such heaer file for each source file that declares static functions.
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopWhat we do for any given module TLA is to have both a tla.h which is Johan's public "contract" and also a tlai.h (i=internal) which is a private header file for information that only needs to be used amongst the components of the module. However we wouldn't put a static function declaration into even the tlai.h. The thole point of "static" is that they are private to the one .c file where they are defined so if the function needs to be announced before it is used a simple declaration would be made within the early sections of the .c
- Log in or register to post comments
TopThanks - sounds good to me. The project now compiles and links with out any errors.
Thank you again.
D
- Log in or register to post comments
Topspliting is very nice idea, as one said you'll especially benefit when using OO languages. The disadvantage is that with separate compilations compiler has much less oportunities to optimize program. For example (AFAIK) it doesn't inline code compiled in other module, it pushes more registers then needed or just leaves unused functions in generated header. Therefore after such spliting user usually should be more compilator-aware - for example ISR that call function should be in same module - function we'll be inlined, or at least only needed registers we'll go to the stack.
- Log in or register to post comments
TopThis is the makefile I'm using with CrossPack for OS X:
How can I edit this to allow adding additional .c files? Right now, I have to do #include "uart.c" to get it to work; which simply embeds said code in main.c rather than having the compiler link it in.
Tried to see if the makefile could first make uart.o from uart.c and then link uart.o and main.o to yield main.hex; not making much progress in this as aspect though.
Thanks in advance for your advice :)
- Log in or register to post comments
TopThe clue seems to be here
It's late, so I wont test it but you could try to add the names of other object to be built to this variable. Eg if your project consists of main.c and uart.c then
You will of-course also have to edit up a uart.h with the things (eg function prototypes, extern declarations of "shared" variables etc) that needs to be seen from both main.c and uart.c and #include that file in both main.c and uart.c .
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopThanks Johan! I did try having uart.o in the OBJECT definition but I was getting this strange error:
expected '=', ',', ';', 'asm' or '__attribute__' before
The reason is that the 'uart.h' header needed the avr/io.h header to be included. For the ref of others, here are my two files as they stand:
uart.h
uart.c
and the beginning of my main.c. It is possible that I could leave out some of them.
- Log in or register to post comments
TopPersonally, when there's a lot of common system headers included in each .c I'd put the #includes in a syshdr.h and then just #include "syshdr.h" in each .c to reduce the "noise". On the occasion that the interrupt header file changes from to I'd then just need to make the change in one place - not edit every .c where it is included.
- Log in or register to post comments
TopYou might want to rename it to syshdr.inc, perhaps, to stress the fact that it is *not* a *header* (i.e. "interface description of a *.c") as such.
JW
- Log in or register to post comments
TopPerhaps. Perhaps not. The use of ".h" as the extension even for nested includes is quite wide-spread.
AFAICR this is the first time I see the notion of making the super-include-files have a filetype of ".inc". Is this a cultural thing, where eg U*ix people do it, and others (eg MS) don't?
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopIn our coding standard it would most definitely be a .h, we do have the concept of ".i" to but that's for the very specific purpose of a block of externally generated const data that MUST only be #include'd in one .c file - the .i rather than .h makes this clear to the casual reader.
- Log in or register to post comments
TopDuring my C/C++ classes at Uni and even most books I have always seen the use of ".h" and never the use of ".inc".
- Log in or register to post comments
TopDoesn't matter what extension you use on a file #include'd in your code -- the preprocessor will process it just the same. That said, personally I think it extremely poor form to use anything other than the .h unless it's something very unusual, like a giant array of PCM audio data which needs to be embedded. Even then, I'd make the embedding of resource files a compile step, and not part of the actual code.
Each to his own, but don't be surprised if you get fired for naming all your C header files "Includes.jpg".
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopIt most definitely isn't a *nix thing. A quick journey through the system headers in a linux install will reveal that many are simply includes of other headers, usually architecture specific. I too have never seen the suggestion to use an extension other than .h for this purpose. Just because a file is used to consolidate common includes, does not make it "not a header".
.inc from my experience is usually reserved for includes in assembly projects.
But as Dean stated, the C compiler does not care what the extension is. #include is simply a text insertion.
Writing code is like having sex.... make one little mistake, and you're supporting it for life.
- Log in or register to post comments
TopA poor practice, however widespread, is still a poor practice. Replace "sub-optimal" for "poor" in the above if you find it offensive.
The choice of extension is arbitrary, but I agree that defacto standards have to be respected. As you might have noticed, I don't have that much of an experience with projects invoving C (I try to avoid them, in fact, being a dedicated C-hater ;-) ). Any other extension would do - fancy .hh?
While it's very easy to implement literal inclusion, it's hard to do it in the proper way. So there's no enforcement of binding the header to the actual source, nor of rejecting irrelevant information from it. There is no syntactical distinction between "include your own header for making sure it matches the body of module", "include a header of the module to be able to link to its functions and variables", and "include an arbitrary text - possibly a collection of headers".
And this is why it is hard to explain to the novices the concept of headers. This thread is in a tutorial section after all, isn't it.
Jan Waclawek
- Log in or register to post comments
TopJan,
You may want to take a look at in AVR-LibC ;-)
Even \Program Files\Microsoft Visual Studio\VC98\include\windows.h is little more than a bunch of #include's
And, as has already been stated, the technique is used a LOT in the Linux kernel tree.
It may not be "good practice" but it's what C programmers have actually been doing in large projects since time immemorial. In fact that includes me in large in-house projects (one with 57,000 .c files) - some are "meta headers" that just group the inclusion of a bunch of other headers.
Cliff
- Log in or register to post comments
TopJan
- Log in or register to post comments
TopWell, yes, actually I do believe that. While people decry Microsoft their own source code is very good quality. The reason people call Windows "buggy" is that it does not isolate driver code enough and when Tom, Dick or Harry get a copy of the DDK and write their own webcam or scanner driver it has the ability to crash the kernel (in fact the same is true of anything that is insmod/modprobe'd into the Linux kernel too). The end user's experience is that "Windows has crashed" but more often than not it's 3rd party driver code that has crashed.
In fact a lot of the coding standard we adhere too is based on the writings of Steve Maguire in Writing Solid Code:
http://www.amazon.com/Writing-So...
He outlines the techniques that Microsoft use internally to avoid the more obvious code faults. If you like it's a bit like a cut-down, less stringent MISRA rule book. That is a very very good book and I highly recommend it to anyone programming in C. While I've had office "purges" over the years and had to discard a lot of books to make room, this remains one of the core books (like K&R, the Borland C reference and Charles Petzold on programming Windows) that I'll retain for all time.
Cliff
- Log in or register to post comments
TopI have never seen anyone who uses a .inc extension for included files in C. In fact, the only variation I have ever really seen other than .h is to use no extension at all (an older practice that has gone out of favor). So I'm not sure how you can say in one breath that you should follow the de facto standard, but in another say to throw the de facto standard out the window only to advocate something else that virtually no one else does.
Regards,
Steve A.
The Board helps those that help themselves.
- Log in or register to post comments
TopWell, using an already "assigned" extension for a different purpose would cause confusion; while using an already "unassigned" extension for the non-interface headers would cause at worst a mild attention.
But of course there's no point to push it beyond reason. There are many controversial items in various coding standards to add one more. The thinking programmer develops his own little variations anyway.
I rest the case.
JW
PS. I googled for "file name extension .i" and learned that it is likely to be an INTERCALC file... :-P
- Log in or register to post comments
TopYou seriously underestimate the value of established conventions and traditions. The existence of a convention is a value as such, even if the convention is (in your imagination) not optimal. You forgot that there isn't black and white only, but that engineering is a string of compromises and most results are grey. You forgot that it is usually a huge waste of time and money to do things perfect (the 80/20 rule of thumb). Engineering is not about perfection.
Stealing Proteus doesn't make you an engineer.
- Log in or register to post comments
Top[wek, standing ashamed in the corner of the room, nodding quietly while concentrating on his yet unshot toes, letting out a sob now and then...]
- Log in or register to post comments
TopHow is it a different purpose? #include is used to include other files, and that is what is being done. There is nothing in the designation ".h" that implies what the content of the file is other than that it is intended to be included by other files.
Regards,
Steve A.
The Board helps those that help themselves.
- Log in or register to post comments
TopThere is a simple cure for case problems: Don't Capitalize!
main(), printf(), int, static, avr/interrupt.h, _asm_, _delay_us... See the pattern? Just say no. And in case you feel like a JavaRebel, ok, but at least be consistent.
The exceptions are things already mentioned, constants, macros, classes, header top ifdef's. F_CPU, DEBUG, DDRA, //FIXME, M_PI, RAND_MAX...
A few outstanding conventions exist, like Makefile with a capital M so it stands out from code and README(.txt) in all caps because that's the first thing that should stand out at a glance.
- Log in or register to post comments
TopI am following this tutorial in order to manage my code...but I did not find the make file? where should I find it??
Thanks,
Ashish
- Log in or register to post comments
TopThere isn't one. But what's the problem? You take the Mfile template. Edit the names of all the C (.c) source files onto the SRC= line, the name of Asm (.S) source files into the ASRC= line and the name of all the C++ (.C) files onto the CPPSRC= line and that's it. Job done.
- Log in or register to post comments
TopI have numbers of global variables in my projects. Is it possible to put all the global variables in one .h file and include this file in all the .c file ?
I am defining the global variables using extern word.
If I am doing this way then it is giving me error
"
(.text.avr-libc.fplib+0x0): multiple definition of `__floatunsisf'
"
- Log in or register to post comments
TopI do this but not how you suggested. As this article hopefully explained there should never be any definitions in a .h file, only declarations. So create a new .c file called something like:
globals.c
and add it to the list of source files to be compiled. Then also create:
globals.h
and #include this in any file that needs access to 'n', 'c' or 'l'
In fact I often take this one stage further and group all the globals in a struct. So I have in the .h file:
then in the global.c I have:
and I access the globals as:
- Log in or register to post comments
TopNo, this will not work. As I'm sure has been explained earlier in this thread you will get duplicate definitions of those variables, and the linker generating errors.
What you should do has also most likely been described earlier in this thread:
- Place definitions of your global variables in one .c source file.
- Add that .c source file to the project so that it gets compiled.
- Put extern declarations of the ame variables in a .h header file.
- Include that .h header file into all .c source files that needs to see the variables.
Example:
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopBy the way I just looked back at your post and the __floatunsisf error is actually because you are using FP functions without linking with libm.a, nothing to do with your own variables (in the case of that particular error message)
- Log in or register to post comments
TopI follow the same.. but still I am getting the same error..
(.text.avr-libc.fplib+0x0): multiple definition of `__floatunsisf'
- Log in or register to post comments
TopCould you please explain how to eliminate this error?
- Log in or register to post comments
TopI followed this solution given by clawson sir in some other thread and now it is not giving me that error.
Thank you so much....
- Log in or register to post comments
TopYes, you can have all your "extern" (publically visible) globals listed in one header file. However, you will still need to place them in one of your .c files as well without the "extern" modifier, otherwise you will receive undefined reference errors.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopI am trying to write a header file and put up everything related to TWI in it, leaving only the main processing to the main.c and functions being called as and when required. I want the TWI ISRs to be contained by this header. The program compiles fine, but somehow the ISR just isn't executing. Could you please help me out with this?
And, should I be using a .c file instead of the .h file.
- Log in or register to post comments
TopAn ISR is effectively just a fancy regular function - and anything that results in actual executable code in the binary should be a .c file rather than a .h file. Try creating a TWI.c and TWI.h pair, with the ISRs in the C file.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopThe snide remark is that you are yet another one that has a problem on line 42 of your source code.
Seriously: We can't say much unless you post your code. It helps boost interest in helping you if you reduce the code to the smallest possible that still builds and executes and displays the problem.
The usual case is a .c file and a .h file. Go read the tutorial here on "Managing large projects".
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopIrony. I love it!
- Log in or register to post comments
TopBlimey! Didn't notice we where already there. :roll:
As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.
No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.
"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]
- Log in or register to post comments
TopThank you for the quick response :) Got it working.
- Log in or register to post comments
TopDean,
You Did not mention where to define ISR routines when splitting a large project into different .c and .h files. Is it in the same file where main() function defined?
-Partha
- Log in or register to post comments
TopI'd put it inside the module where it is most relevant, i.e. the module that sets up the ISR.
- Dean :twisted:
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopOne key thing is if the ISR() calls any functions then either make them static inline - in which case they could actually be located in a .h file - otherwise put them in the same .c file where the ISR() is located so the compiler has some chance of determining register usage and will not be forced to save/restore the entire context.
- Log in or register to post comments
TopRegards,
Steve A.
The Board helps those that help themselves.
- Log in or register to post comments
TopHey Guys,
Quick question. With custom data types how does the extern tag work? For something like the following:
In the .c file:
How would you declare the .h file? I have tried different extern syntax and can't seem to get right.
I have tried the following:
.h file:
I get the following errors:
Following warning on the structure call:
warning: useless keyword or type name in empty declaration
Following error on the custom MyStructure call:
error: syntax error before "outputsArray"
Thanks in advance!
- Log in or register to post comments
TopTry:
You want the variable definition of that type to be extern, not the declaration of the type.
- Dean :twisted:
(EDIT: Fixed wrong definition/declaration terminology - always get it round the wrong way!)
Make Atmel Studio better with my free extensions. Open source and feedback welcome!
- Log in or register to post comments
TopTo add to what Dean says. A typedef does not create any storage. A definition of the array of struct does. The only things you want to avoid in a header file are anything that leads to storage being allocated. So it's the variable definition that needs to be turned into a declaration only. You do this by adding 'extern'.
- Log in or register to post comments
TopSorry if this was already asked.
Not explicitly said this tutorial seems to indicate that say "usart.h" does not need to include "usart.c" is that true?
- Log in or register to post comments
TopPages