Memory-mapped devices as C++ classes

June 22, 2010

Dan_Saks-June 22, 2010

Last month, I examined some common alternatives for representing and manipulating memory-mapped devices in C.1 The techniques I presented work as well (or as badly) in C++. However, classes in C++ offer a better alternative than anything you can do in C. This month, I'll explain why.

Picking up where I left off
As I did last month, I'll use for my examples a machine with a variety of devices, including a programmable timer, which employs a small collection of device registers. The timer registers start at location 0xFFFF6000.

For simplicity, I assume that every device register is a four-byte word aligned to an address that's a multiple of four, so that you can manipulate each device register as an unsigned int or, equivalently, as a uint32_t. Since device registers are volatile entities, I typically bundle the volatile qualifier with the appropriate integer type within a typedef definition, as in:

typedef uint32_t volatile device_register;

In C, structures often provide the best way to model the device registers of memory-mapped devices. For example:

typedef uint32_t volatile device_register;

typedef struct timer_registers timer_registers;
struct timer_registers
    device_register TMOD;
    device_register TDATA;
    device_register TCNT;

defines the layout for a timer with three device registers.

The header (.h) file that defines this structure might also define useful constants and types for manipulating the registers, such as:

#define TE 0x01
#define TICKS_PER_SEC 50000000

typedef uint32_t timer_count_type;

which defines TE as a mask for setting and clearing the timer enable bit in the TMOD register, TICKS_PER_SEC as the number of times the timer's TCNT register can decrement in one second, and timer_count_type as the type of an object that can hold the TCNT register's value. That header should also declare functions that provide basic operations for programming a timer, such as:

void timer_disable(timer_registers *t);
void timer_enable(timer_registers *t);
void timer_set(timer_registers *t, timer_count_type c);
timer_count_type timer_get(timer_registers const *t);

< Previous
Page 1 of 4
Next >

Loading comments...