Critical review of GPIO wrapper class
I done a reviewI've received reviews on the last version in this threadhere , but as an update would make the answers not fitting anymore, I think it is wise to open a new threadpost.
So I followed most of the hints of the last review and now want to check if I done things write or made new mistakes.
Bodo
Critical review of GPIO wrapper class
I done a review on the last version in this thread but as an update would make the answers not fitting anymore I think it is wise to open a new thread.
So I followed most of the hints of the last review and now want to check if I done things write or made new mistakes.
Bodo
GPIO wrapper class
I've received reviews on the last version here , but as an update would make the answers not fitting anymore, I think it is wise to open a new post.
I followed most of the hints of the last review and now want to check if I done things write or made new mistakes.
Critical review of GPIO wrapper class
I done a review on the last version in this thread but as an update would make the answers not fitting anymore I think it is wise to open a new thread.
So I followed most of the hints of the last review and now want to check if I done things write or made new mistakes.
If you are interested in the complete source click here
gpio.h
#ifndef SRC_GPIO_H_
#define SRC_GPIO_H_
#include <string>
#include <fstream>
#include <iostream>
using std::string;
using std::fstream;
enum GPIODirection {
GPIO_IN = 0,
GPIO_OUT = 1
};
enum GPIOValue {
GPIO_LOW = 0,
GPIO_HIGH = 1
};
class GPIO {
public:
explicit GPIO(int id);
~GPIO();
int Value();
void Value(int value);
int Direction();
void Direction(int value);
private:
int id_;
fstream value_;
fstream direction_;
bool Exists();
void Export();
void Unexport();
static const string PATH_EXPORT;
static const string PATH_UNEXPORT;
static const string PREFIX;
static const string POSTFIX_VALUE;
static const string POSTFIX_DIRECTION;
};
#endif
gpio.cc
#include "gpio.h"
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <exception>
#include <stdexcept>
using std::ios;
using std::endl;
using std::string;
using std::stringstream;
using std::logic_error;
using std::runtime_error;
const string GPIO::PATH_EXPORT = "/sys/class/gpio/export";
const string GPIO::PATH_UNEXPORT = "/sys/class/gpio/unexport";
const string GPIO::PREFIX = "/sys/class/gpio/gpio";
const string GPIO::POSTFIX_VALUE = "/value";
const string GPIO::POSTFIX_DIRECTION = "/direction";
GPIO::GPIO(int id) {
id_ = id;
Export();
stringstream value_path;
stringstream direction_path;
value_path << PREFIX;
value_path << id;
value_path << POSTFIX_VALUE;
direction_path << PREFIX;
direction_path << id;
direction_path << POSTFIX_DIRECTION;
value_.open(value_path.str().c_str());
direction_.open(direction_path.str().c_str());
}
GPIO::~GPIO() {
value_.close();
direction_.close();
Unexport();
}
bool
GPIO::Exists() {
stringstream path;
path << PREFIX;
path << id_;
fstream gpio;
gpio.open(path.str().c_str());
bool result = gpio.good();
gpio.close();
return result;
}
void
GPIO::Export() {
if (Exists()) return;
fstream gpio_export;
stringstream string_stream;
string_stream << id_;
gpio_export.open(PATH_EXPORT.c_str(), ios::out);
gpio_export << string_stream.str();
gpio_export.close();
}
void
GPIO::Unexport() {
if (!Exists()) return;
fstream gpio_unexport;
stringstream string_stream;
string_stream << id_;
gpio_unexport.open(PATH_UNEXPORT.c_str(), ios::out);
gpio_unexport << string_stream.str();
gpio_unexport.close();
}
int
GPIO::Value() {
string value;
value_.seekp(0);
value_ >> value;
if (value == "0") return GPIO_LOW;
if (value == "1") return GPIO_HIGH;
throw logic_error("Invalid GPIO value.");
}
void
GPIO::Value(int value) {
value_.seekp(0);
switch (value) {
case GPIO_LOW:
value_ << "0" << endl;
if (!value_.good())
throw runtime_error("Error writting to value file stream.");
break;
case GPIO_HIGH:
value_ << "1" << endl;
if (!value_.good())
throw runtime_error("Error writting to value file stream.");
break;
default:
throw logic_error("Error cannot set invalid GPIO value.");
}
}
int
GPIO::Direction() {
string direction;
direction_.seekp(0);
direction_ >> direction;
if (direction == "in") return GPIO_IN;
if (direction == "out") return GPIO_OUT;
throw logic_error("Invalid GPIO direction.");
}
void
GPIO::Direction(int value) {
direction_.seekp(0);
switch (value) {
case GPIO_IN:
direction_ << "in" << endl;
if (!direction_.good())
throw runtime_error("Error writting to direciton file stream.");
break;
case GPIO_OUT:
direction_ << "out" << endl;
if (!direction_.good())
throw runtime_error("Error writting to direciton file stream.");
break;
default:
throw logic_error("Error cannot set invalid GPIO direction.");
}
}
Things I guess could be done better:
- class methods
- implementation of Exist()
- error handling
- string formatting
- path constants
- int to string cast (std::to_string seems not to be available)
Bodo