Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid globals in this case (embedded C)

I'm still learning C to be used in microprocessors. In the beginning I used lots of globals. Now I'm trying to avoid it as much as a can, but for me it's not always clear to see how to do this.

For example a battery monitor, in this case there are 4 functions that need to read or modify a variable. I have these functions all using the variable LowVoltage.

void Check_Voltage(){
  checks current voltage against LowVoltage
}

void Menu_Voltage(){
  a menu on the LCD screen to set the value of LowVoltage
}

void Save_LowVoltage(){
 runs after the settings menu is finished to save LowVoltage to EEPROM
}

void Load_LowVoltage(){
 reads EEPROM and sets LowVoltage at startup 
}
  • Check_Voltage() and Save_LowVoltage() need to read LowVoltage.
  • Load_LowVoltage() need to write LowVoltage.
  • Menu_Voltage() needs to read and write LowVoltage.

How can I make this work without making LowVoltage global?? Would I need to make another function to read or write LowVoltage? Something like this:

unsigned int Low_Voltage(short Get, unsigned int Value){
  static unsigned int LowVoltage;

  if(Get) return LowVoltage;
  else LowVoltage= Value;
}

Or are there better ways to do this? I guess there must be :) I've been reading about structures lately, but to be honest I don't fully understand them and I'm not even sure it would help me in cases like this?

like image 964
Benno Avatar asked Mar 30 '15 14:03

Benno


1 Answers

There are several choices to sharing a variable among functions:

  • Allocate your variable in static memory - this is pretty much what your code does. Your two choices there are function-static, translation unit-static, and global
  • Pass a pointer to variable as function parameter - This choice requires passing the pointer around in some form
  • Use thread-local storage with clever initialization - This choice is not usually available when you work with microcontrollers; I list it here for completeness.

In your case, I think that using a translation unit-static variable would be appropriate. Put implementations of the four functions into a single C file, and declare LowVoltage at the top as a static variable:

static unsigned int LowVoltage;

This simple but efficient encapsulation mechanism gives you all benefits of having a global variable, without the drawbacks of having a global variable:

  • All functions inside the C module "see" this variable, and can freely manipulate it
  • No other functions outside the C module can access this variable. They can declare their own LowVoltage variable, giving it an entirely different meaning.
like image 116
Sergey Kalinichenko Avatar answered Sep 21 '22 05:09

Sergey Kalinichenko