树莓派3B的地址映射问题堪称新手噩梦,我用几步给大家演示一下

2022-04-12   大方老师单片机

原标题:树莓派3B的地址映射问题堪称新手噩梦,我用几步给大家演示一下

树莓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 MMUARM物理地址进行映射。我现在是要操GPIO,我们来看GPIO的地址映射。

首先我们需要知BCM2835IO基址装载0x20000000,但BCM2837有一点不同是装载0x3F000000,这可以从官方文档获知:Raspberry Pi Documentation - Raspberry Pi Hardware

那么现IOVC CPU总线上的基址0x7E000000,在物理地址上的基址0x3F000000

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

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

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

///插播一条:我自己在今年年初录制了一套还比较系统的入门单片机教程,想要的同学找我拿就行了免费的,私信我就可以~点我头像黑色字体加我也能领取///

欢迎大家有问题一起交流,指出其中的不足之处,谢谢大家。