樹莓派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硬體地址了。

///插播一條:我自己在今年年初錄製了一套還比較系統的入門單片機教程,想要的同學找我拿就行了免費的,私信我就可以~點我頭像黑色字體加我也能領取///

歡迎大家有問題一起交流,指出其中的不足之處,謝謝大家。