19.10.2012 Views

Designing and Building Portable Systems in C++ - Applied Informatics

Designing and Building Portable Systems in C++ - Applied Informatics

Designing and Building Portable Systems in C++ - Applied Informatics

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

W<strong>in</strong>dows <strong>and</strong> Unix platforms, <strong>and</strong> support for embedded/real-time operat<strong>in</strong>g systems is<br />

limited, if available at all. It most be noted that us<strong>in</strong>g such a library only br<strong>in</strong>gs one half the<br />

way towards true cross-platform programm<strong>in</strong>g. The other half is a solid underst<strong>and</strong><strong>in</strong>g of all<br />

the <strong>C++</strong> cross-platform programm<strong>in</strong>g issues, as discussed <strong>in</strong> this paper.<br />

4 Interfac<strong>in</strong>g Hardware<br />

Us<strong>in</strong>g the object-oriented features of <strong>C++</strong>, hardware can be easily represented by classes. The<br />

same technique that has been used for abstract<strong>in</strong>g operat<strong>in</strong>g system facilities can be used for<br />

abstract<strong>in</strong>g hardware. Alternatively, public <strong>in</strong>heritance together with protected virtual member<br />

functions can be used to implement different versions of devices with the same <strong>in</strong>terface.<br />

4.1 Input/Output Ports<br />

The methods for access<strong>in</strong>g <strong>in</strong>put/output ports are highly platform specific. Not even the<br />

POSIX specification def<strong>in</strong>es a st<strong>and</strong>ard API for this. At the lowest level, an I/O register can<br />

be represented as a class. For example, us<strong>in</strong>g the private <strong>in</strong>heritance technique:<br />

class IOReg16: private IOReg16Imp<br />

{<br />

public:<br />

IOReg16(UIntPtr addr);<br />

void set(UInt16 value);<br />

UInt16 get() const;<br />

};<br />

This, aga<strong>in</strong>, can be used as a build<strong>in</strong>g block for a higher-level abstraction, for example a<br />

digital-to-analog converter (DAC):<br />

class DAC<br />

{<br />

public:<br />

DAC(IOReg16& reg);<br />

void set(float voltage);<br />

const float MAX_VOLTAGE = 2.4;<br />

private:<br />

IOReg16& _ioReg;<br />

};<br />

DAC::DAC(IOReg16& reg): _ioReg(reg)<br />

{<br />

}<br />

<strong>in</strong>l<strong>in</strong>e void DAC::set(float voltage)<br />

{<br />

_ioReg.set((UInt16) (voltage*0xFFFF/MAX_VOLTAGE));<br />

}<br />

4.2 Interrupts<br />

Interrupt service rout<strong>in</strong>es (ISRs) can be written <strong>in</strong> <strong>C++</strong>, provided the RTOS has some basic<br />

support for writ<strong>in</strong>g ISRs <strong>in</strong> <strong>C++</strong> or C. If not, the use of assembly language or platformspecific<br />

language extensions might be required to use <strong>C++</strong> code <strong>in</strong> an ISR, due to<br />

<strong>in</strong>compatible call<strong>in</strong>g conventions. The code implement<strong>in</strong>g an ISR should be as short as<br />

possible. The non time-critical parts of h<strong>and</strong>l<strong>in</strong>g an <strong>in</strong>terrupt should be loaded off to a<br />

separate thread. An event queue (implemented as a static r<strong>in</strong>g buffer, s<strong>in</strong>ce no memory can be<br />

allocated <strong>in</strong> an ISR) can be used to pass data from the ISR to the h<strong>and</strong>ler thread. It is then<br />

15

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!