For each register definition in the memory map file a corresponding #define is generated in the header file. The #define is named the same as the register name and is defined as a volatile pointer to the address.

The type of the pointer is derived from the size of the register. A four-byte register generates an unsigned long pointer. A two-byte register generates an unsigned short pointer. A one-byte register will generates an unsigned char pointer.

If a register definition in the memory map file has bitfields then preprocessor symbols are generated for each bitfield. Each bitfield will have two preprocessor symbols generated, one representing the mask and one defining the start bit position. The bitfield preprocessor symbol names are formed by prepending the register name to the bitfield name. The mask definition has _MASK appended to it and the start definition has _BIT appended to it.

For example consider the following definitions in the the file memorymap.xml.

<RegisterGroup start="0xFFFFF000" name="AIC">
  <Register start="+0x00" size="4" name="AIC_SMR0">
    <BitField size="3" name="PRIOR" start="0" />
    <BitField size="2" name="SRCTYPE" start="5" />
  </Register>
  ...

We can generate the header file associated with this file using:

mkhdr memorymap.xml memorymap.h 

This generates the following definitions in the file memorymap.h.

#define AIC_SMR0 (*(volatile unsigned long *)0xFFFFF000)
#define AIC_SMR0_PRIOR_MASK 0x7
#define AIC_SMR0_PRIOR_BIT 0
#define AIC_SMR0_SRCTYPE_MASK 0x60
#define AIC_SMR0_SRCTYPE_BIT 5

These definitions can be used in the following way in a C/C++ program:

Reading a register
unsigned r = AIC_SMR0;
Writing a register
AIC_SMR0 = (priority << AIC_SMR0_PRIOR_BIT) | (srctype << AIC_SMR0_SRCTYPE_BIT);
Reading a bitfield
unsigned srctype = (AIC_SMR0 & AIC_SMR0_SRCTYPE_MASK) >> AIC_SMR0_SRCTYPE_BIT;
Writing a bitfield
AIC_SMR0 = (AIC_SMR0 & ~AIC_SMR0_SRCTYPE_MASK) | ((srctype & AIC_SMR0_SRCTYPE_MASK) << AIC_SMR0_SRCTYPE_BIT);