Reputation: 5074
QUESTION:
For educational purposes, I'm in the process of trying to understand exactly how the RaspberryPI interfaces with its GPIO headers. I have a simple program that control an LED on an expansion board that works well. However, I wanted to use GDB to see the program changing bits in the mapped control registers. Normally I would do something like this in GDB:
x /t 0x20200000
But this seems to result in the following error, presumably as the target memory is not in the process space:
0x20200000: Cannot access memory at address 0x20200000
I tried mapping a memory region but didn't seem to help.
mem 0x20200000 0x20208192
I also true to write a function to call from GDB, but couldn't figure out how to write something that returned entire block of memory I am interested in so can view as binary (I don't want to peek each byte as write bits are quite spread out over area). Is there any way I can do this in GDB?
Memory addresses to map:
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
Pointer to mapped memory:
static volatile uint32_t *gpio ;
Mapping routine:
int gpio_init (void)
{
int fd ;
uint8_t *gpioMem;
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0)
{
fprintf (stderr, "gpio_init: unable to open /dev/mem: %s\n", strerror (errno)) ;
return -1 ;
}
if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL)
{
fprintf (stderr, "gpio_init: malloc failed: %s\n", strerror (errno)) ;
return -1 ;
}
if (((uint32_t)gpioMem % PAGE_SIZE) != 0)
gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ;
gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ;
if ((int32_t)gpio < 0)
{
fprintf (stderr, "gpio_init: mmap failed: %s\n", strerror (errno)) ;
return -1 ;
}
return 0 ;
}
Upvotes: 1
Views: 1649
Reputation: 239171
The physical memory address 0x20200000
is being mapped into your process address space at an address stored in the variable gpio
, so that's the address you should be examining in gdb
. Just print the contents of gpio
after gpio_init()
has been called and use that value.
As an aside the way the mapping is done is confused. There is no need to allocate a memory block with malloc
and then map over it, and it also fails to close the file descriptor. That entire function could be better written as:
int gpio_init (void)
{
int fd ;
if ((fd = open ("/dev/mem", O_RDWR) ) < 0)
{
fprintf (stderr, "gpio_init: unable to open /dev/mem: %s\n", strerror (errno)) ;
return -1 ;
}
gpio = mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ;
if (gpio == MAP_FAILED)
{
fprintf (stderr, "gpio_init: mmap failed: %s\n", strerror (errno)) ;
close(fd);
return -1 ;
}
close(fd);
return 0 ;
}
Upvotes: 2