Memory-mapped devices as C++ classes
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);


Loading comments... Write a comment