I am asked this:
Using your RPi, write a C function that reads the free running system
timer. The system timer counts up every microsecond. Place the
source for this function its own file. The free running timer is a 64
bit value located at physical memory address 0x20003004, however, the
RPi can only access 32 bits at a time in this memory area. To access
these memory locations mmap() will be called on the file /dev/mem.
Be sure to always check for and act appropriately to errors. To
access the system timer:
(a) Check to see if the counter is mapped by
testing a static variable.(b) If the counter is not mapped then
i.
open /dev/men read only.ii. get the system page size
iii. call
mmap() and save the returned address (pointer to 32 bit integers) in a
static variable. call mmap() by allowing mmap() to set the address
mapping. Set the length to the page size. Set the protection to
read only. Set the flags to a shared map. Next, pass the file
descriptor returned by open(), and then set the offset to 0x20003000.
Remember, for this case, mmap() can only operate on pages of
__SC_PAGESIZE bytes, so the address 0x20003004 cannot be directly mapped – the address must be __SC_PAGESIZE aligned.iv. Set the
static variable to indicate that initialization has occurred.v.
Close the open file.(c) If initialization is successful, return a 64
bit number by combing the 32 bit value at index 1 with the 32 bit
value at index 2. The 32 bit value at index 1 contains the least
significant 32 bits of the counter. The 32 bit value at index 2
contains the most significant 32 bits of the counter. Otherwise
return 0.
I was able to get the contents of the timer for the first memory location 0x20003000 :
int main(int argc, char * argv[])
{
int temp;
int page_size;
int *map;
temp = open("/dev/mem", O_RDONLY);
page_size = sysconf(_SC_PAGESIZE);
map = mmap(0, page_size, PROT_READ, MAP_SHARED, temp, 0x20003000);
printf("%X \n", map);
close(temp);
return 0;
}
I am lost at the part where it asks me to get the other 32 bit number 0x20003004 and combine it with the original. Any help or guidance it welcome.
From your quoted description:
What this means is that
mmap()can only map to addresses that are aligned to__SC_PAGESIZE. It also means that the address returned bymmap()can be dereferenced up topage_size. I.e., if the call tommap()with0x20003000returns0x20003000, you can dereference pointers within[0x20003000, 0x20003000 + page_size).I’ll leave the rest as an exercise for the reader.