问题:
出于教育目的,我正在尝试准确理解RaspberryPI如何与其GPIO标头连接。我有一个简单的程序来控制扩展板上的LED运行良好。但是,我想使用GDB来查看映射控制寄存器中的程序更改位。通常我会在GDB中做这样的事情:
x /t 0x20200000
但是这似乎导致了以下错误,大概是因为目标内存不在进程空间中:
0x20200000: Cannot access memory at address 0x20200000
我尝试映射内存区域,但似乎没有帮助。
mem 0x20200000 0x20208192
我也写了一个从GDB调用的函数,但是无法弄清楚如何编写返回我感兴趣的整个内存块的东西,所以可以查看为二进制(我不想查看每个字节)因为写位在区域上非常分散)。 我有什么方法可以在GDB中做到这一点吗?
要映射的内存地址:
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
指向映射内存的指针:
static volatile uint32_t *gpio ;
映射例程:
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 ;
}
答案 0 :(得分:2)
物理内存地址0x20200000
被映射到存储在变量gpio
中的地址的进程地址空间中,因此这是您应该在gdb
中检查的地址。只需在调用gpio
后打印gpio_init()
的内容,然后使用该值。
另外,映射完成的方式很混乱。不需要使用malloc
分配内存块然后映射它,它也无法关闭文件描述符。整个函数可以更好地写成:
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 ;
}