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
volatile_AH
PostPosted: Sep 04, 2008 - 03:01 PM
Newbie


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

Thanks to your help JohanEkdahl, and a bit of fiddling... I managed to get it to all compile (and probably more important learned something along the way Smile ).

Now to start playing with this doxygen to get some some nice documentation out of it...
 
 View user's profile Send private message  
Reply with quote Back to top
jay warren
PostPosted: Sep 20, 2008 - 05:40 AM
Hangaround


Joined: Mar 14, 2004
Posts: 281
Location: Philippines

Glad to be back here... Smile

Im not sure if this may help but, one may also use function table in declaring functions, specially those that almost have the same characteristics (ie communication protocols that sends, receives data).

For example:

Code:

From Protocol.h
#define INIT   0
#define TXDATA 1
#define RXDATA 2


From Protocol.c
void (*Protocol[][Idx])() =
{
#if defined (UART)
    ProtocolInit[Idx] = UartInit();
    ProtocolTxData[Idx] = UartTxData();
    ProtocolRxData[Idx] = UartRxData();

#elif
    ProtocolInit[Idx] = SpiInit();
    ProtocolTxData[Idx] = SpiTxData();
    ProtocolRxData[Idx] = SpiRxData();
#endif
}


The Idx refers to the UART channel.

From the calling function, one may only need to call

Code:
Protocol[INIT][Idx]


if the UART or SPI needs to be initialized, depending on the channel (Idx). If you are using 2 UART, you set Idx to either 0 or 1, depending on which UART you want to initialize.

Code:
Protocol[TXDATA][Idx]


to transmit data,
and

Code:
Protocol[RXDATA][Idx]


to get the data.

I haven't compiled this code yet so there might be some missing or erroneous syntax. Please feel free to correct me.

Thanks. Smile

Nice tutorial, dean.
 
 View user's profile Send private message  
Reply with quote Back to top
eel
PostPosted: Nov 11, 2008 - 08:01 PM
Newbie


Joined: Nov 03, 2008
Posts: 1


Quote:

Header files should NEVER directly output code when included


Quote:

What happends when you want to take one piece of the developed source code and use in another project.


Indeed. How does a statement like #include <stdio.h> allow you to use functions like printf()?

Thanks,

-Stephen
 
 View user's profile Send private message  
Reply with quote Back to top
bojan.m
PostPosted: Feb 17, 2009 - 05:30 PM
Newbie


Joined: May 19, 2008
Posts: 17


Thanks for this very good tutorial! Very Happy

I'm just re-organising a large project, but I've got some problems with global vars.

this is my situation:
I've got several source files with their headers
main(.c .h) UART(.c.h) EEPROM(.c .h) ...
I've got a Constants.h with some defines that are used in the whole project and need to be included everywhere, as th GlobalHeader.h where i put some type defs and library includes.

1) those headers that go everywhere stay better in c files or in every header? (i.e. changes something if I put Constants.h in main.c or main.h etc...)

2) I've got a compilation error (undeclared variable) on global vars. I've got some global (whole project) vars which I declared at the beginning of the main.c as
Code:
uint8_t checkSend;

and in the main.h as
Code:
extern uint8_t checkSend;

now I got errors compiling UART.c whic uses those global vars. Do I need to put the extern uint8_t checkSend; in headers of every file wich uses this var?

Thanks,
-bo.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Feb 17, 2009 - 05:50 PM
10k+ Postman


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

You should have a vars.h (or something) that documents the globally accessible variables in main.c and #include this wherever one or more of those variables need to be accessed.

It should only be necessary to have the extern declaration of any particular variable definition in a .c file made in one .h file - then #include that file where visibility is required.

If it were me I think I'd #include main.h, uart.h and eeprom.h (perhaps also <avr/io.h> etc) in globalheaders.h and then just #include that one file in each .c file.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
bojan.m
PostPosted: Feb 17, 2009 - 06:04 PM
Newbie


Joined: May 19, 2008
Posts: 17


ok, thanks!
I'll include those vars as a sub section of the GlobalHeader.h, which goes everywhere...
bye,
bo.
 
 View user's profile Send private message  
Reply with quote Back to top
damien_d
PostPosted: Feb 28, 2009 - 05:58 AM
Resident


Joined: Dec 15, 2008
Posts: 923
Location: Brisbane, Australia

A few other little hints along the same lines.

* Include as FEW header files in other files as far as is possible for several reasons:

(1) You can quickly tell what modules are **really** dependant on other modules.

(2) Compile time. OK, AVR compile time is relatively short, but wait until you do a complex C++ project using lots and lots of template functions. You'll definitely appreciate this rule then!

* Include the header files in order of custom.h through to the standard libraries. You'll have less dependency problems when porting the sources to something else.

When separating out functionality, I usually group related files in a directory. It then makes it very easy to branch this directory into another project and track/merge changes between the two of them. See comments on a source control system below Smile

And, not directly related to C programming (so I expect to get flamed), but I strongly recommend the following:

(a) Learn C++, or a reasonably close-to-metal Object-oriented Language, even if it's for doing basic host-side work. My C code (and even assembly!) is cleaner, more portable and far more maintainable after learning an OO language and putting various practices in place.

(b) There is no excuse whatsoever (and I really, really mean that) for not using a version control system. Even if you're an only-programmer or hobbyist on a project. One day, you'll break something and wonder what you did to break it.

Subversion is free, open source and cross-platform, both command line and graphical for Windows and *nix.

(c) C99 includes nice features like inline, restrict and const that, when used correctly, will make code safer and faster in many scenarios.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Feb 28, 2009 - 12:33 PM
10k+ Postman


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

Quote:

Subversion is free, open source and cross-platform, both command line and graphical for Windows and *nix.

Agree and if using Windows then Tortoise is a nice interface. But if you are in Linux also consider Git which is the new pretender to the SVN crown (possibly because it was written by Linus Torvalds with the needs of version managing the Linux kernel in mind)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
frnando_2006
PostPosted: Feb 28, 2009 - 01:08 PM
Rookie


Joined: Aug 25, 2006
Posts: 23


Thanks for the great tutorial Dean!!

Very useful and clear!!
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Feb 28, 2009 - 02:02 PM
10k+ Postman


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

Quote:
But if you are in Linux also consider Git

AFAIK Git is available on Windows also.

Quote:

consider Git which is the new pretender to the SVN crown

I'd say that there is a troika of contenders: Bazaar, Git and Mercurial. There are Windows Explorer-integrated GUIs available for all three (TortoiseBzr, TortoiseGit and TortoiseHg).
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
damien_d
PostPosted: Mar 01, 2009 - 12:33 AM
Resident


Joined: Dec 15, 2008
Posts: 923
Location: Brisbane, Australia

JohanEkdahl wrote:


I'd say that there is a troika of contenders: Bazaar, Git and Mercurial. There are Windows Explorer-integrated GUIs available for all three (TortoiseBzr, TortoiseGit and TortoiseHg).


We'll leave the revision control wars for another thread Razz

In the meantime, a good list can be found at http://en.wikipedia.org/wiki/List_of_re ... l_software
 
 View user's profile Send private message  
Reply with quote Back to top
cloudburst
PostPosted: Apr 30, 2009 - 09:48 AM
Newbie


Joined: Apr 29, 2009
Posts: 9


Is agreeing with the positive comments on this thread

-Jd from the land of the Pacman
 
 View user's profile Send private message  
Reply with quote Back to top
derelectt
PostPosted: Jul 31, 2009 - 08:45 AM
Newbie


Joined: May 22, 2009
Posts: 3


Hi 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:

Quote:
../SDCard.h:108: warning: 'SendCommand_SDC' declared 'static' but never defined



Code:
//In .h file
static BOOL SendCommand_SDC(uint8_t uchCommand, uint32_t uiArgument, uint8_t *puchResponse);


Code:

//In .c file
static BOOL SendCommand_SDC(uint8_t uchCommand, uint32_t uiArgument, uint8_t *puchResponse)
{
...code
}


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
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jul 31, 2009 - 08:57 AM
10k+ Postman


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

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.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Jul 31, 2009 - 09:32 AM
10k+ Postman


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

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

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
derelectt
PostPosted: Jul 31, 2009 - 03:35 PM
Newbie


Joined: May 22, 2009
Posts: 3


Thanks - sounds good to me. The project now compiles and links with out any errors.

Thank you again.
D
 
 View user's profile Send private message  
Reply with quote Back to top
kwesoly
PostPosted: Sep 07, 2009 - 01:37 AM
Newbie


Joined: Aug 17, 2009
Posts: 3


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.
 
 View user's profile Send private message  
Reply with quote Back to top
bsodmike
PostPosted: Sep 09, 2009 - 10:30 PM
Newbie


Joined: Sep 09, 2009
Posts: 12
Location: Colombo, Sri Lanka

This is the makefile I'm using with CrossPack for OS X:

Code:
# Name: Makefile
# Author: <insert your name here>
# Copyright: <insert your copyright message here>
# License: <insert your license reference here>

# 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.

Thanks in advance for your advice Smile
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohanEkdahl
PostPosted: Sep 09, 2009 - 10:56 PM
10k+ Postman


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

The clue seems to be here
Quote:

Code:
# 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
Code:
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 .
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
bsodmike
PostPosted: Sep 09, 2009 - 11:17 PM
Newbie


Joined: Sep 09, 2009
Posts: 12
Location: Colombo, Sri Lanka

JohanEkdahl wrote:
...

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:

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
Code:
#ifndef USART_H
#define USART_H

#include <stdint.h>
#include <avr/io.h>

uint8_t uart_putchar (char data);
uint8_t uart_getchar (void);
void uart_putstring(char *s);

#endif


uart.c
Code:
#include "uart.h"

uint8_t uart_putchar (char data)
{
   while ( !( UCSRA & (1<<UDRE)) ); // Wait for empty transmit buffer           
   UDR = data;  // Putting data into the buffer, forces transmission                               
   return 0;
}

uint8_t uart_getchar (void)
{
   while ( !(UCSRA & (1<<RXC)) );  // Wait for data to be received           
   return (UDR);        // Return Data                         
}

void uart_putstring(char *s)
{
   while(*s) uart_putchar(*s++);
   
}


and the beginning of my main.c. It is possible that I could leave out some of them.

Code:
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "uart.h"
 
 View user's profile Send private message Visit poster's website 
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