-1

This question is about programming but as its about programming electronics so I thought of posting it here instead of stackoverflow . I have just started my electronics projects. I have designed two applications and have done their hardware and firmware part myself. Here in this question I want to know how to write an efficient C program and how to manage all the files in the project.

Lets say in an application, we have below parts:

  1. GPIOs
  2. Serial Communication
  3. RTC (I2C Communication)
  4. SD Card (SPI Communication)

The way I work is to create different files for every module. Like for Serial Communication:

//serial.c  

//function to initialize serial communication
void serialInit()
{

}
//function to send data
void serialSend()
{

}
//function to receive data
void serialReceive()
{

}

So in serial.c I have made all the required functions for serial communication.

//serial.h

void serialInit();
void serialSend();
void serialReceive();

/*
* All the variable used in serialInit(), serialSend(), serialReceive().
* char rxData = 0;
* int i,j=0; ..etc
*/

and in serial.h I include all the variables used in serial.c. Same goes for every file like rtc.c rtc.h sdcard.c sdcard.h. I main.c I include all the header files:

//main.c
#include "serial.h"
#include "rtc.h"
#include "sdcard.h"

main.c contain all the logic and programming part. All the variable used inside main.c is defined in main.h. Now problem sometime occurs here. As main.h contains all the variables and if I need to include main.h in any other source file, it gives error: multiple definition. I have searched for this error and have found many solutions to it. I want to know the effective of handling this problem. What are some good practice for designing firmwares. Is the way I am writing is correct way or not. What are other methods for handling major embedded firmwares.?

S Andrew
  • 621
  • 11
  • 29

1 Answers1

4

Overall your division of functionality across the different files looks good, but you shouldn't be defining variables in a .h file.
The .h file is more for sharing variable & functions with other modules.
So only variables which you want to share should be listed in your .h file and they should all be declared with 'extern' as the first word in the declaration.
Variables which are only used inside the corresponding .c file should not be declared in the .h file.
Function declarations don't need an extern.

So for your serial.h example, what you should have is something like:

//serial.h

void serialInit();
void serialSend();
void serialReceive();

/*
* variables which are exposed to other modules in your code
*/
extern char rxData = 0;  

/* These variables are not exposed and only used inside serial.c
*  They're only here as an example and should be deleted from this .h file entirely
*  int i,j=0;   
*/

Note that not declaring a variable in a .h file doesn't actually prevent another code module from accessing it if it 'knows' about it.
The way to prevent other modules from accessing 'private' variables is to declare them as 'static' in your .c file.
This makes the variable still 'global' inside that file, but inaccessible from outside.

When you declare functions in a .h file, you can declare them as you have done with no parameters specified - just using () - if your functions don't take any parameters.
I prefer to explicitly define the parameters each function is expecting, so for example:

void serialSend(void *buf, int len);  

or

void serialSend(void);  

if your function really doesn't take any parameters.

This lets the compiler check that when you call this function that you're passing the correct type & number of parameters.
Just using () means that you're allowed to call the function with as many parameters of whatever type you like - even though it doesn't actually take any.

brhans
  • 14,723
  • 3
  • 35
  • 51