Monday, December 3, 2007

How to use mmap

#include sys/mman.h
#include stdio.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.h

int fd_wd;
void *wd_addr = NULL;
unsigned char *temp;
volatile unsigned int *addr;

#define BASE 0xF0010000

int main (int argc, char *argv[])
{
char dat[4096] = "12345678";
unsigned int i, base_addr, read;
unsigned int store;
unsigned int value;
unsigned short page_size;

page_size = getpagesize ();
if(argc == 1)
{
printf ("Usage : ./mapper [options] \n");
printf (" Options 1 - to mmap local array \n");
printf (" 2 - to map fixed addr 0xF0010000 \n");
printf (" 3 - to map new address and new file eg: ./mapper 3 /dev/mem\n");
return 1;
}
if (atoi(argv[1]) != 1)
{
if(argc == 3)
{
printf("Openning file %s \n",argv[2]);
fd_wd = open (argv[2], O_RDWR | O_SYNC);
if (fd_wd == -1)
{
perror("Open ");
return 1;
}

}
else
{
fd_wd = open ("/dev/mem", O_RDWR | O_SYNC);
printf (" Opening file /dev/mem file \n");
if (fd_wd == -1)
{
perror("While Open ");
return 1;
}
}
if(atoi(argv[1]) == 3 )
{
printf(" Enter 32bit addr eg 0xF0010000 \n Hex 0x");
scanf("%X",&base_addr);
}
else
{
base_addr = BASE;

}
/* mmap() will read only page by page , so BASE should be multiple of Page Size */
if ((base_addr % page_size) != 0)
{
printf (" Base address is not multiple of pagesize ");
return 1;
}
/*page_size will length ,since 0-(lenght-1) = length eg: if size 4096 ...start 0-4095 */
wd_addr = mmap (0, (page_size - 1), PROT_READ | PROT_WRITE, MAP_SHARED, fd_wd, base_addr);
perror (" Memory mapping ");
if (wd_addr == (void *) -1)
{
printf ("Unable to map mem file \n");
perror (" Failed: ");
close (fd_wd);
return 1;
}
}
else
{
printf (" Local mapping to Array \n");
wd_addr = dat;
}

/* Printing the Address */
printf (" wd_addr = %X ", wd_addr);

/*Reading Byte by Byte */
temp = (unsigned char *) wd_addr;
printf ("\n\n Enter Offset [0-%d] : ", (page_size - 1));
scanf ("%d", &read);
/* Moving the pointer to Entered offset */
store = *(temp);
temp = temp + read;
printf (" Reading 4 bytes : \n");
for (i = 0; i < 4; i++)
{
printf (" Addr[%02d] : %X = %02X \n", i, temp, *(temp));
temp++;
}

/*Reading Word by Word */
addr = (unsigned int *) wd_addr;
value = *(addr);
value = *(addr);
printf ("\n Base Addr: %X by Word 0x%08X \n", addr, value);
printf ("\n Enter offset [0-4095] to read word : ");
scanf ("%x", &read);

addr = addr + ((unsigned int) read / 4); /* Asuming 4byte == one word length
it is an 32 it processor */
printf (" Enter no. of words to Read:");
scanf ("%d", &read);
/*In big endian format first readed byte is will not match with truncated byte from Word */
if (store != (unsigned char) value)
printf ("\n Big-endian platform Lsb....Msb \n");
else
printf ("\n Little-endian plat Msb....Lsb \n");
for (i = 0; i < read; i++)
{
value = 0;
value = *(addr);
printf (" Addr[%d] : %X 0x%08X \n", i, addr, value);
addr++;
}
printf ("\n");

if (atoi(argv[1]) != 1)
printf (" Munmap : %d\n", munmap (wd_addr, page_size));
return 0;
}

No comments: