Last active
August 29, 2015 14:20
-
-
Save carlos-jenkins/b8ee29962ce7524394f6 to your computer and use it in GitHub Desktop.
Example of a register structure that can be memory mapped
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example of a memory mapped register structure: | |
// | |
// gcc register.c -o register | |
// ./register | |
// | |
// This assumes register size is 8bits. | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <string.h> | |
// pragma directives are required to pack the structure. | |
// This depends on your architecture, in particular, if your registers width | |
// and entries are aligned to the data bus width then this isn't required. | |
// Though, this is not always the case. | |
// Push current alignment to stack and set alignment to 1 byte boundary | |
#pragma pack(push) | |
#pragma pack(1) | |
struct registers { | |
// First register bank | |
struct { | |
// Simple 8 bit register | |
uint8_t simple8; | |
// Bit field register | |
struct { | |
uint8_t b1 : 1; | |
uint8_t b2 : 1; | |
uint8_t bspecial : 4; | |
uint8_t btrailer1 : 1; | |
uint8_t btrailer2 : 1; | |
} bitfieldreg; | |
} firstbank; | |
// Empty padding of 10 registers | |
uint8_t padding1[10]; | |
// Second register bank | |
struct { | |
// Yet another simple register with the same name in another bank | |
uint8_t simple8; | |
// Overloaded register with two different definitions | |
union { | |
struct { | |
uint8_t c1 : 2; | |
uint8_t c2 : 2; | |
uint8_t cspecial : 4; | |
} overloaded1; | |
struct { | |
uint8_t d1 : 6; | |
uint8_t d2 : 1; | |
uint8_t d3 : 1; | |
} another; | |
}; | |
// Multiple instances of a register (indexed) | |
uint8_t instacesreg[10]; | |
} secondbank; | |
// Third bank, instanced 3 times | |
struct { | |
uint8_t myreg; | |
struct { | |
uint8_t e1 : 4; | |
uint8_t e2 : 3; | |
uint8_t e3 : 1; | |
} anotherreg; | |
} thirdbank[3]; | |
}; | |
// Restore original alignment from stack | |
#pragma pack(pop) | |
int main() | |
{ | |
// Offcourse we use malloc to simulate the memory space, in other | |
// circunstances use a casting to the start position of the memory: | |
// | |
// volatile struct registers *iospace = (struct registers*)0x40000000; | |
// | |
struct registers* iospace = | |
(struct registers*) malloc(sizeof(struct registers)); | |
if (iospace == NULL) { | |
printf("Unable to allocate memory for registers simulation.\n"); | |
return -1; | |
} | |
memset(iospace, rand() & 0xFF, sizeof(struct registers)); | |
printf( | |
"Register base has a size of: %zu bytes\n", | |
sizeof(struct registers) | |
); | |
printf("Current value for the registers (random initialized):\n"); | |
printf("-- First Bank:\n"); | |
printf("simple8:%d\n", iospace->firstbank.simple8); | |
free(iospace); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment