Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Comments on Pattern / architecture for interfacing with components in C
Post
Pattern / architecture for interfacing with components in C
I'm working on the architecture, where the assumption is to easily extend the options in the system and also to provide some kind of encapsulation (from the main we could only access the type1 / type2 through interface). It will be an embedded software system, where there will be e.g. the same end device, but different inputs (digital or analog). I want to use the same interface to get the signal, but it could be handled in different ways. Each functionality will have its implementation, but the final signal will be the same and will be handed over to the next function.
I'm wondering about declaring the pointers in type*.h and using them in type*.c in this way
type1.h
extern stType1 *type1_object;
Is it proper to variable declaration, definition and use in the function in this way? It compiles, but could it be used in that way?
type1.c
static stType1 memReservation;
stType1 *type1_object = &memReservation;
bool getOneType1()
{
return type1_object->internalOne;
}
Whole code below:
interface.h
#ifndef _INTERFACE_H
#define _INTERFACE_H
#include <stdbool.h>
#include <stdint.h>
#define DIGITAL 0
#define ANALOG 1
typedef struct hwInterface hwInterface;
struct hwInterface
{
void (*cyclic)();
bool (*getOne)();
bool (*getTwo)();
};
// common interface
extern hwInterface *hwInterfaceX;
void init(uint8_t Type);
void initType1();
void initType2();
#endif
interface.c
#include "interface.h"
static hwInterface memReservation;
hwInterface *hwInterfaceX = &memReservation;
void init(uint8_t Type)
{
// program depend from parameter
if (Type == DIGITAL)
{
initType1();
}
else if (Type == ANALOG)
{
initType2();
}
}
type1.h
#include <stdio.h>
#include "interface.h"
typedef struct stType1
{
hwInterface interface;
bool internalOne;
bool internalTwo;
} stType1;
extern stType1 *type1_object;
/////////////////////////
// INTERFACE FUNCTIONS //
/////////////////////////
void cyclicType1();
bool getOneType1();
bool getTwoType1();
///////////////////////
// PRIVATE FUNCTIONS //
///////////////////////
void type1Printer();
type1.c
#include "type1.h"
static stType1 memReservation;
stType1 *type1_object = &memReservation;
/////////////////////////
// INTERFACE FUNCTIONS //
/////////////////////////
void cyclicType1()
{
// Read digital inputs, some logic //
// write to own variables //
type1Printer();
}
bool getOneType1()
{
return type1_object->internalOne;
}
bool getTwoType1()
{
return type1_object->internalTwo;
}
//////////////////////////
// INITIALIZATION //
//////////////////////////
void initType1()
{
printf("Init Type1 function\n");
type1_object->interface.cyclic = &cyclicType1;
type1_object->interface.getOne = &getOneType1;
type1_object->interface.getTwo = &getTwoType1;
hwInterfaceX = (hwInterface*)type1_object;
type1_object->internalOne = false;
type1_object->internalTwo = true;
}
///////////////////////
// PRIVATE FUNCTIONS //
///////////////////////
void type1Printer()
{
printf("Cyclic type1 own function\n");
}
type2.h
#include <stdio.h>
#include "interface.h"
typedef struct stType2
{
hwInterface interface;
bool internalOne;
bool internalTwo;
} stType2;
extern stType2 *type2_object;
/////////////////////////
// INTERFACE FUNCTIONS //
/////////////////////////
void cyclicType2();
bool getOneType2();
bool getTwoType2();
///////////////////////
// PRIVATE FUNCTIONS //
///////////////////////
void type2Printer();
type2.c
#include "type2.h"
static stType2 memReservation;
stType2 *type2_object = &memReservation;
/////////////////////////
// INTERFACE FUNCTIONS //
/////////////////////////
void cyclicType2()
{
// Read digital inputs, some logic //
// write to own variables //
type2Printer();
}
bool getOneType2()
{
return type2_object->internalOne;
}
bool getTwoType2()
{
return type2_object->internalTwo;
}
//////////////////////////
// INITIALIZATION //
//////////////////////////
void initType2()
{
printf("Init Type2 function\n");
type2_object->interface.cyclic = &cyclicType2;
type2_object->interface.getOne = &getOneType2;
type2_object->interface.getTwo = &getTwoType2;
hwInterfaceX = (hwInterface*)type2_object;
type2_object->internalOne = true;
type2_object->internalTwo = false;
}
///////////////////////
// PRIVATE FUNCTIONS //
///////////////////////
void type2Printer()
{
printf("Cyclic type2 own function\n");
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "interface.h"
void display(bool input)
{
printf("%d\n", input);
}
int main()
{
uint8_t Type = DIGITAL;
//////////////////////
// READ PARAMETERS //
//////////////////////
printf("Choose type (0 - DIG, 1 - ANALOG): ");
scanf("%hhd", &Type);
// INITIALIZATION //
init(Type);
while(1)
{
/////////////////////////////////////////////////////
// cyclic - access posible only through interface //
/////////////////////////////////////////////////////
hwInterfaceX->cyclic();
// external block (display) reads footboards state from interface
display(hwInterfaceX->getOne());
display(hwInterfaceX->getTwo());
// some delay
for(volatile uint32_t i = 0; i < 700000000; i++);
}
return 0;
}
1 comment thread