Is this a valid / good method to prevent global variables using C firmware?

I looked at this topic for a long time and persistently to avoid global variables and came up with a way to do it, which I actually did not see anywhere in my search, which leads me to believe it, maybe not the best way to do it (or I just do not formulate your search is correct).

As an example, I have something like this:

int16_t DataProcessing(uint8_t CallType, struct DataStruct *DataIO) { int16_t RetVal; static struct DataStruct StaticDataStuct; switch (CallType) { case FIRSTCASE: RetVal = FirstCaseProcessing(&StaticDataStuct,DataIO); break; case SECONDCASE: RetVal = SecondCaseProcessing(&StaticDataStuct,DataIO); break; ... etc ... } return RetVal; } int16_t FirstCaseProcessing(struct DataStruct *StaticData, struct DataStruct *NewData) { // Do what you need to do here } 

Same idea for any other routines that call.

I also performed wrapper functions to call DataProcessing (), which makes it all a lot easier to read and for new people to use it in the future. So for example:

 int16_t FirstCase(uint8_t Address, uint16_t Data) { struct DataStruct NewData; NewData.Address = Address; NewData.Data= Data; return DataProcessing(FIRSTCASE, &NewData); } 

So what seems good is that, apart from interrupts like UARTs and timers, I have no global variables at all. (I still think that getting into and out of interrupts as soon as possible is better than having an interrupt in order to store something in a static variable somewhere, but I'm happy that they convince me otherwise.)

What can [bad] be that I pass the material through three functions in the interest of avoiding globalization and makes it more readable (assuming that it’s not only that I consider it readable!)

I would say that I was provided with a built-in 32-bit processor with a frequency of 72 MHz to do what could be done with an eight-bit processor running at a fraction of the speed (provided that it has enough RAM). Thus, speed is not a problem, although I am interested in opinions about whether it is a good style when speed can be more problematic.

I saw a C ++ style having .c files and having static variables that any function inside this .c file can see and access (but external files cannot), passing values ​​/ pointers, etc. inside and out with access functions, but they seem to use what I think are variables that are "global" to the file (or local to the file, depending on how you want to look at it!). In addition, it is possible to have one function that stores a static variable and simply passes a pointer to this static variable for everything that it wants to access. I am wondering if this will be OTT?

Is my idea good / bad / terrible?

Thanks so much for any advice and all the TL, DR that I'm probably going to get .; ~)

+4
source share
1 answer

OP: Does my idea sound good / bad / terrible?

A good OP is not OTT yet.

Avoiding global variables in inline constructs is a good goal, primarily for the sake of maintenance. Hiding information (creating local data for a function or object) is the key to managing many interactions and simplifying debugging. This is especially true for the OP processor faster (and probably more memory).


An alternative is to hide data in the file area.

The OP solution looks hierarchically, as with DataProcessing() , command and input / output parameters are set, and DataStruc data is known at this level.

I am aiming for a more data-based approach using a pointer or index and a set of routines. Say, in the firmware, I need, at most, Sally_N instances of the Sally variable. Here, my data is not global, but hidden in the Sally.c file area. Thus, the data and its detailed fields are hidden far from the higher level code that uses it. In the OP approach, the details of the DataStruct known to function at a higher level, DataProcessing() .

 // Sally.h struct Sally_t; // Does not expose the fields extern struct Sally_t *Sally_Init(...); extern void Sally_DoThis(struct Sally_t *, ...); extern void Sally_DoThat(struct Sally_t *, ...); // Sally.c struct Sally_t { int a, ... }; // Structure details static struct Sally_t Sally_Data[Sally_N];// file scope prevents global exposure struct Sally_t *Sally_Init(...); void Sally_DoThis(struct Sally_t *, ...); void Sally_DoThat(struct Sally_t *, ...); 
0
source

Source: https://habr.com/ru/post/1501446/


All Articles