关于树莓派Pi 3B的地址映射问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/windsnow1/article/details/88164415

关于树莓派Pi 3B的地址映射问题

摘要:

在设备驱动程序的开发过程中,我们通常需要跟硬件地址打交道。在不带操作系统的嵌入式平台上(譬如单片机,STM32等),我们直接操作的是硬件物理地址。但是在基于Linux的嵌入式平台上,我们需要与操作系统打交道。操作系统操作的是虚拟地址,因此我们有将物理地址映射成为虚拟地址的操作。

我使用的硬件平台是树莓派Raspberry Pi 3 Model B,处理器芯片是BCM2837。我想用树莓派直接控制引脚电平高低(简单的GPIO操作)。官方没有提供BCM2837芯片手册,但是提供了BCM2835芯片手册。BCM2837架构是在BCM2835上做了改变,但是基本不变。下载BCM2835的手册,看其地址映射【第4页】。

从这个图标中我们可以看到三个地址,一个是ARM虚拟地址,一个是ARM物理地址。它们之间通过ARM MMU来映射。还有一个是VC CPU总线地址。这是我们直接操作寄存器的地址,VC CPU 总线地址通过VC/ARM MMU与ARM物理地址进行映射。我现在是要操作GPIO,我们来看看GPIO的地址映射。

首先我们需要知道BCM2835的IO基址装载在0x20000000,但是BCM2837有一点不同是装载在0x3F000000,这可以从官方文档获知:https://www.raspberrypi.org/documentation/hardware/raspberrypi/peripheral_addresses.md 。

那么现在IO在VC CPU总线上的基址是0x7E000000,在物理地址上的基址是0x3F000000。

我么来看操作GPIO的寄存器,现在假设我需要操作GPIO2,输出高电平。查阅BCM2835芯片手册【89-90页】:

我们只需要操作GPFSEL0寄存器(GPIO0-GPIO9的功能选择寄存器),GPSET0寄存器(设置GPIO0-GPIO31高电平寄存器)。现在只需要获取这两个寄存器的地址即可。

我们发现GPFSEL0寄存器VC CPU总线地址是0x7E200000,相对基址偏移0x00200000,那么ARM物理地址也是偏移这么多,其ARM物理地址是0x3f200000。同理,GPSET0的ARM物理地址是0x3f20001C。我们在嵌入式Linux中,可以使用mmap函数或者ioremap函数将这两个ARM物理地址映射成虚拟地址,就等同于直接操作GPIO硬件地址了。

这是我在各路网路大咖,大牛博文的参照下,学习到的一点小知识。欢迎大家有问题一起交流,指出其中的不足之处,谢谢大家。

猜你喜欢

转载自blog.csdn.net/windsnow1/article/details/88164415