Languages/C/SplitCH

(Difference between revisions)
Jump to: navigation, search
(Temperature sensor example)
(main.c)
Line 29: Line 29:
 
}
 
}
  
=== temp_sensor.h ===
 
 
</source>
 
</source>
 
<source lang='c'>
 
<source lang='c'>
 +
=== temp_sensor.h ===
  
 
#ifndef TEMP_SENSOR_H // (3) prevent multiple inclusion, see the #endif at the end
 
#ifndef TEMP_SENSOR_H // (3) prevent multiple inclusion, see the #endif at the end
Line 51: Line 51:
 
#endif /* TEMP_SENSOR_H */
 
#endif /* TEMP_SENSOR_H */
  
=== temp_sensor.c ===
 
  
 
</source>
 
</source>
 +
=== temp_sensor.c ===
 +
 
<source lang='c'>
 
<source lang='c'>
 
/**
 
/**

Revision as of 13:49, 10 December 2013

Contents

Source and header file split

It is sometimes complicated to split the header and the source file, here are some hints:

  • (1) The header MUST contain what is necessary from the outside of the source file.
  • (2) The header SHOULD NOT contain, what is not necessary.
    • There is no reason to pollute the namespace of the whole project.
    • Keeping the interface small and as clean as possible will make team work simpler.
  • (3) The header file MUST prevent multiple inclusion
  • (4) A header file SHOULD be complete (it defines or includes all it needs).
    • Example, if you use a uint32_t parameter in a function, the header should include <stdint.h>
  • (5) A header file SHOULD not include files only used in source file
  • (6) The header SHOULD be commented enough so there is no need to open the source file.
  • (7) The source file MUST include the header, preferably first
    • This will ensure consistency
  • (8) All symbols not exported by the header
    • Do not pollute the linker namespace

Temperature sensor example

Here is a small example, using main.c, temp_sensor.h, and temp_sensor.c

main.c

#include <stdio.h>
#include "temp_sensor.h"
 
int main(int argc, char *argv[])
{
	return printf("temperature is : %d", temp_sensor_get());
}
=== temp_sensor.h ===
 
#ifndef TEMP_SENSOR_H // (3) prevent multiple inclusion, see the #endif at the end
#define TEMP_SENSOR_H
 
#include <stdint.h> // (4) We use stdint in the interface !
 
// (6) Full comments, no need to open temp_sensor.c
// (1) This function is needed in main
/**
 * \brief Get the temperature
 *
 * \return the temperature in K.
 *
 * \waring the value will be 0 if the sensor read fails.
 */
uint16_t temp_sensor_get(void);
 
#endif /* TEMP_SENSOR_H */

temp_sensor.c

/**
 * \file temp_sensor.c
 *
 * \brief Temperature sensor driver implementation
 */
 
#include "temp_sensor.h" // (7) Include the header for compile-time checks
#include <super_os/i2c.h> // (2) The i2c bus is not used in main
 
// (2) These defines are private, we don't want to see them in main
#define SENSOR_ADDRESS 0x12
#define SENSOR_REG 0x33
 
// (8) this function is not exported -> static
// (6) this function MUST be commented here
/**
 * \brief Do the real work here
 * \param chip, the i2c address of the chip
 * \param address, the address in the chip
 * \param value, where to store the value
 * \return 0 for no problem
 */
static uint8_t read(uint8_t chip, uint8_t address, uint16_t *value)
{
	if (i2c_read(SENSOR_ADDRESS, SENSOR_REG, value, 2) != 0)
	{
		return 0;
	}
 
	return 1;
}
 
// (6) This function is already commented in the header
uint16_t temp_sensor_get(void)
{
	uint16_t temp;
	uint8_t status = read(SENSOR_ADDRESS, SENSOR_REG, &temp);
 
	// Do what is said in temp_sensor.h
	if (status)
	{
		temp = 0;
	}
 
	return temp;
}
Personal tools
Namespaces
Variants
Actions
Navigation
Browse
Toolbox