MUP1+Øvelse+10+Driver

toc =User Space Access to Device Drivers=

GenericDevice
En abstrakt klasse som wrapper IO funktionerne til en char device driver. Bemærk konstruktøren er privat så der ikke kan oprettes objekter af denne klasse, men derimod kun af nedarvede klasser.

GenericDevice.h
code format="cpp" class GenericDevice { public: enum OpenMethod { READ, WRITE, READWRITE }; virtual ~GenericDevice; bool openDevice; void closeDevice; void readDevice; void writeDevice; char* getValue; void setValue(char*); protected: GenericDevice(std::string, OpenMethod); private: std::string fileName; std::fstream fileDescriptor; OpenMethod parameters; char value[ARRAY_SIZE]; std::_Ios_Openmode translateEnum(OpenMethod); }; code

GenericDevice.cpp
code format="cpp"
 * 1) include "GenericDevice.h"

GenericDevice::GenericDevice(std::string fileName, OpenMethod parameters) {	this->fileName = fileName; this->parameters = parameters; }

GenericDevice::~GenericDevice {	closeDevice; }

void GenericDevice::writeDevice {	fileDescriptor.write(value, sizeof(writeValue)); }

void GenericDevice::closeDevice {	fileDescriptor.close; }

char* GenericDevice::getValue {	return value; }

void GenericDevice::setValue(char* value) {	this->value = value; }

bool GenericDevice::openDevice {	std::string nodePath = "/dev/" + fileName;

fileDescriptor.open(nodePath.c_str, translateEnum(parameters));

if (!fileDescriptor.is_open) {		printf("Failed to open %s\n", nodePath.c_str); return false; }	return true; }

void GenericDevice::readDevice {	fileDescriptor.read(value, sizeof(value)); }

std::_Ios_Openmode GenericDevice::translateEnum(OpenMethod openMethod) {	if (openMethod == READ) return std::fstream::in; if (openMethod == WRITE) return std::fstream::out; if (openMethod == READWRITE) return std::fstream::in | std::fstream::out; return std::fstream::in; } code

ConcreteDevice
Denne klasse er en konkret implementering, som benytter sig af Singleton pattern for at sikre at der kun er ét objekt der kan læse og skrive til driveren.

ConcreteDevice.h
code format="cpp"
 * 1) include "GenericDevice.h"

class ConcreteDevice : public GenericDevice { public: static ConcreteDevice* getInstance(std::string); ~ConcreteDevice; protected: static ConcreteDevice* instance; private: ConcreteDevice(std::string); }; code

ConcreteDevice.cpp
Bemærk variable instance. Grunden til den er oprettet i global scope er fordi den er static, så kompileren kan holde styr på hvornår den skal nedlægges. code format="cpp"
 * 1) include "ConcreteDevice.h"

ConcreteDevice* ConcreteDevice::instance = NULL;

ConcreteDevice::ConcreteDevice(std::string fileName) : GenericDevice(fileName, GenericDevice::READ) { }

ConcreteDevice::~ConcreteDevice {	delete instance; }

ConcreteDevice *ConcreteDevice::getInstance(std::string fileName) {	return instance ? instance : (instance = new ConcreteDevice(fileName)); } code