chipace
Posts: 77
Joined: Sat Jun 29, 2019 2:56 am
Location: brown paper bag in a septic tank

Rapberry pi 4 IO memory base address

Sat Jun 29, 2019 3:26 am

Anyone know the RPi 4 base IO address (and the offset for GPIO)?

This is what I used for RPi 3:
#define BCM2708_PERI_BASE 0x3F000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)

Thanks.

User avatar
DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Rapberry pi 4 IO memory base address

Sat Jun 29, 2019 12:37 pm

This has been mentioned over in the baremetal sub-forum here:

Raspberry Pi 4

See the post:
Raspberry Pi 4: CPU and peripherals base addresses: by gothicknight
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

User avatar
joan
Posts: 14376
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Rapberry pi 4 IO memory base address

Sat Jun 29, 2019 1:50 pm

Peripheral base is 0xFE000000.

Peripheral offsets are unchanged (as far as I can tell).

chipace
Posts: 77
Joined: Sat Jun 29, 2019 2:56 am
Location: brown paper bag in a septic tank

Re: Rapberry pi 4 IO memory base address

Sat Jun 29, 2019 8:37 pm

Thanks joan! My gpio is working great now.
I used a simple C program to toggle one pin as fast as possible and I am measuring 12.5MHz (80ns period with 25% duty cycle).

User avatar
joan
Posts: 14376
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Rapberry pi 4 IO memory base address

Sat Jun 29, 2019 9:24 pm

chipace wrote:
Sat Jun 29, 2019 8:37 pm
Thanks joan! My gpio is working great now.
I used a simple C program to toggle one pin as fast as possible and I am measuring 12.5MHz (80ns period with 25% duty cycle).
What code are you using for the toggle? I thought it might be a bit faster as I think the GPIO are connected differently (I may well have misremembered or misinterpreted something I read).

dl324
Posts: 122
Joined: Mon May 06, 2019 7:33 pm
Location: Pacific Northwest, USA

Re: Rapberry pi 4 IO memory base address

Sun Jun 30, 2019 12:35 am

chipace wrote:
Sat Jun 29, 2019 8:37 pm
I used a simple C program to toggle one pin as fast as possible and I am measuring 12.5MHz (80ns period with 25% duty cycle).
I get 17MHz from Pi 0; 29MHz with compiler optimization.

chipace
Posts: 77
Joined: Sat Jun 29, 2019 2:56 am
Location: brown paper bag in a septic tank

Re: Rapberry pi 4 IO memory base address

Mon Jul 01, 2019 5:32 am

Here's the code. I found it on-line. I am not very familiar with C.
If you have a more simple code example, I would very much like to use it.

Code: Select all

//
//  How to access GPIO registers from C-code on the Raspberry-Pi
//  Example program
//  15-January-2012
//  Dom and Gert
//  Revised: 15-Feb-2013


// Access from ARM Running Linux

#define BCM2708_PERI_BASE        0x3F000000
#define BCM2711_PERI_BASE        0xFE000000
#define GPIO_BASE                (BCM2711_PERI_BASE + 0x200000) /* GPIO controller */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

int  mem_fd;
void *gpio_map;

// I/O access
volatile unsigned *gpio;


// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |=  (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

#define GPIO_SET *(gpio+7)  // sets   bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0

#define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH

#define GPIO_PULL *(gpio+37) // Pull up/pull down
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock

void setup_io();

void printButton(int g)
{
  if (GET_GPIO(g)) // !=0 <-> bit is 1 <- port is HIGH=3.3V
    printf("Button pressed!\n");
  else // port is LOW=0V
    printf("Button released!\n");
}

int main(int argc, char **argv)
{
  int g,rep;

  // Set up gpi pointer for direct register access
  setup_io();

  // Switch GPIO 7..11 to output mode

 /************************************************************************\
  * You are about to change the GPIO settings of your computer.          *
  * Mess this up and it will stop working!                               *
  * It might be a good idea to 'sync' before running this program        *
  * so at least you still have your code changes written to the SD-card! *
 \************************************************************************/

  // Set GPIO pin 21 to output
  INP_GPIO(21); // must use INP_GPIO before we can use OUT_GPIO
  OUT_GPIO(21);

  for (rep=0; rep<10000; rep++)
  {
     GPIO_SET = 1<<21;
     GPIO_SET = 1<<21;
     GPIO_CLR = 1<<21;
     GPIO_CLR = 1<<21;
  }

  return 0;

} // main


//
// Set up a memory regions to access GPIO
//
void setup_io()
{
   /* open /dev/mem */
   if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
      printf("can't open /dev/mem \n");
      exit(-1);
   }

   /* mmap GPIO */
   gpio_map = mmap(
      NULL,             //Any adddress in our space will do
      BLOCK_SIZE,       //Map length
      PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
      MAP_SHARED,       //Shared with other processes
      mem_fd,           //File to map
      GPIO_BASE         //Offset to GPIO peripheral
   );

   close(mem_fd); //No need to keep mem_fd open after mmap

   if (gpio_map == MAP_FAILED) {
      printf("mmap error %d\n", (int)gpio_map);//errno also set!
      exit(-1);
   }

   // Always use volatile pointer!
   gpio = (volatile unsigned *)gpio_map;


} // setup_io

Heater
Posts: 13683
Joined: Tue Jul 17, 2012 3:02 pm

Re: Rapberry pi 4 IO memory base address

Mon Jul 01, 2019 5:44 am

chipace,

I did an experiment like yours a year or so ago. Using Dom and Gerts example code. I added a simple loop to toggle an I/O pin as fast as possible.

On a Pi 3 I achieved a 50MHz toggle rate. https://www.raspberrypi.org/forums/view ... 3&start=25

Be aware that when doing that under Raspbian there will be all kinds of stutters and delays that upset the goggle timing as the Linux kernel reschedules tasks, handles interrupts etc.

To achieve an almost continuous toggle at a constant rate I had to take the precaution of running the code on it's own isolated core that Linux was prevented from scheduling anything on. Methods for doing that are described in the the thread linked above.
Memory in C++ is a leaky abstraction .

User avatar
DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Rapberry pi 4 IO memory base address

Tue Jul 02, 2019 10:15 pm

Just out of curiosity (not yet having a RPi 4B):

Has anyone figured how much of the peripheral address space is the same layout, relative to the base address, for the Raspberry Pi 4B as for earlier Raspberry Pi's?

Also is there any difference in the mailbox channels for communicating with the GPU firmware?

Just
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

User avatar
joan
Posts: 14376
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Rapberry pi 4 IO memory base address

Tue Jul 02, 2019 10:58 pm

Peripheral offsets appear to be the same. Tested GPIO, SYST, SPI, DMA, PWM.

I only use the mailbox to allocate/free memory. That works as before.

User avatar
DavidS
Posts: 4334
Joined: Thu Dec 15, 2011 6:39 am
Location: USA
Contact: Website

Re: Rapberry pi 4 IO memory base address

Tue Jul 02, 2019 11:56 pm

joan wrote:
Tue Jul 02, 2019 10:58 pm
Peripheral offsets appear to be the same. Tested GPIO, SYST, SPI, DMA, PWM.

I only use the mailbox to allocate/free memory. That works as before.
Thank you for that. That tells me that a lot of my code for the RPi 1 B, 2B, and 3B/3B+ should work with just a change of periphial base on the RPi 4B (so for many things no need to reinvent the wheel, as it were). Still going to be interesting to learn about USB, PCIe, and Ethernet on the RPi 4B though.

Thank you for the information.
RPi = The best ARM based RISC OS computer around
More than 95% of posts made from RISC OS on RPi 1B/1B+ computers. Most of the rest from RISC OS on RPi 2B/3B/3B+ computers

User avatar
Paul Webster
Posts: 807
Joined: Sat Jul 30, 2011 4:49 am
Location: London, UK
Contact: Twitter

Re: Rapberry pi 4 IO memory base address

Wed Jul 03, 2019 6:21 am

Is there an official way to get the base address at runtime (i.e. not using defines).

With older Raspbian builds it could be found via /proc/iomem
with different keywords depending whether or not device tree was being used.


https://www.raspberrypi.org/forums/view ... p?t=100066

Edit: changed /dev to /proc as had misremembered
Last edited by Paul Webster on Thu Jul 04, 2019 11:57 am, edited 1 time in total.

User avatar
joan
Posts: 14376
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Rapberry pi 4 IO memory base address

Wed Jul 03, 2019 7:12 am

Not official but something like:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
   FILE *fp;
   uint32_t base;
   unsigned char buf[12];
   if (fp = fopen("/proc/device-tree/soc/ranges" , "rb"))
   {
      if (fread(buf, 1, sizeof(buf), fp) >= 8)
      {
         base = buf[4]<<24 | buf[5]<<16 | buf[6]<<8 | buf[7];
         if (!base)
            base = buf[8]<<24 | buf[9]<<16 | buf[10]<<8 | buf[11];
         printf("peri base is %x\n", base);
      }
      fclose(fp);
   }
}

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 23924
Joined: Sat Jul 30, 2011 7:41 pm

Re: Rapberry pi 4 IO memory base address

Wed Jul 03, 2019 8:59 am

Paul Webster wrote:
Wed Jul 03, 2019 6:21 am
Is there an official way to get the base address at runtime (i.e. not using defines).

With older Raspbian builds it could be found via /dev/iomem
with different keywords depending whether or not device tree was being used.


https://www.raspberrypi.org/forums/view ... p?t=100066
There is a standard function, but its not yet been updated to have the correct value for Pi4. It's in our issues list.

https://www.raspberrypi.org/documentati ... dresses.md
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
“I think it’s wrong that only one company makes the game Monopoly.” – Steven Wright

User avatar
Paul Webster
Posts: 807
Joined: Sat Jul 30, 2011 4:49 am
Location: London, UK
Contact: Twitter

Re: Rapberry pi 4 IO memory base address

Wed Jul 03, 2019 9:40 am

I have created an issue on LCDProc github with link to this.
I submitted a change to LCDProc for older RPi when base changed for the first time - but this time around it is probably best to fix it in a more generic way.

What timescale for the updated official way and how backwards compatible will it be (i.e. will it work on old RPi that are not running Buster) if developers include the required files?

User avatar
Paul Webster
Posts: 807
Joined: Sat Jul 30, 2011 4:49 am
Location: London, UK
Contact: Twitter

Re: Rapberry pi 4 IO memory base address

Thu Jul 04, 2019 6:10 am

Update from LCDProc ... they now consider having specific RPi module for GPIO-based devices as obsolete and instead they want to control via libgpiod.
So ... quick question ... does libgpiod know about the RPi4 base address or whatever it needs to access them?

Edit:
Someone with access to RPi4 (mine is nowhere near me) and something on GPIO could use
gpioinfo pinctrl-bcm2835
assuming that is still the correct name.

rudiratlos
Posts: 146
Joined: Tue May 01, 2012 8:47 am

Re: Rapberry pi 4 IO memory base address

Thu Jul 04, 2019 9:39 am

cat /proc/iomem | grep gpio@

produces the following output on different plattforms:

rpi4: fe200000-fe2000b3 : gpio@7e200000
rpi2-3x: 3f200000-3f2000b3 : gpio@7e200000
zerow: 20200000-202000b3 : gpio@7e200000

e.g. just subtract the GPIO-BaseAddr 0x00200000 from fe200000 or 3f200000 or 20200000 and you will get the PeripheralBaseAddr (PBase) for each pi


iomem is better than using:
xxd -ps -c250 /proc/device-tree/soc/ranges

this creates strange output (I do not understand for rpi4):
ZeroW: 7e0000002000000002000000...
3B+: 7e0000003f00000001000000400000004000000000001000
4B: 7e00000000000000fe000000018000007c00000000000000fc000000020000004000000000000000ff80000000800000

User avatar
Paul Webster
Posts: 807
Joined: Sat Jul 30, 2011 4:49 am
Location: London, UK
Contact: Twitter

Re: Rapberry pi 4 IO memory base address

Thu Jul 04, 2019 12:11 pm

The change that I submitted to LCDProc in 2015 did something similar.
However, those particular fields have disappeared ... so someone using the above code would also need something like my stuff below if it is required to run on older Raspbian systems

extract from the diff ...

Code: Select all

+       if ((fp = fopen("/proc/iomem", "r")) != NULL) {
+               /* Would expect this to be present but perhaps not on all supported OS so not fatal */
+               /* Check to see if setting shows the GPIO base value */
+               while (!feof(fp)) {
+                       fgets(buf, sizeof(buf), fp);
+                       /* from Device Tree-enabled B+ - 20200000-202000b3 : /soc/gpio */
+                       if (strstr(buf, "/soc/gpio") != NULL) {
+                               sscanf(buf, "%x-%x : /soc/gpio", &gpio_base, &gpio_top);
+                       }
+                       /* without Device Tree - 20200000-20200fff : bcm2708_gpio */
+                       if (strstr(buf, "bcm2708_gpio") != NULL) {
+                               sscanf(buf, "%x-%x : bcm2708_gpio", &gpio_base, &gpio_top);
+                       }
+               }

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7434
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Rapberry pi 4 IO memory base address

Thu Jul 04, 2019 2:43 pm

rudiratlos wrote:
Thu Jul 04, 2019 9:39 am
cat /proc/iomem | grep gpio@

produces the following output on different plattforms:

rpi4: fe200000-fe2000b3 : gpio@7e200000
rpi2-3x: 3f200000-3f2000b3 : gpio@7e200000
zerow: 20200000-202000b3 : gpio@7e200000

e.g. just subtract the GPIO-BaseAddr 0x00200000 from fe200000 or 3f200000 or 20200000 and you will get the PeripheralBaseAddr (PBase) for each pi


iomem is better than using:
xxd -ps -c250 /proc/device-tree/soc/ranges

this creates strange output (I do not understand for rpi4):
ZeroW: 7e0000002000000002000000...
3B+: 7e0000003f00000001000000400000004000000000001000
4B: 7e00000000000000fe000000018000007c00000000000000fc000000020000004000000000000000ff80000000800000
Look at the source DT rather than the compiled version.
https://github.com/raspberrypi/linux/bl ... 5.dtsi#L20
https://github.com/raspberrypi/linux/bl ... 36.dtsi#L8
https://github.com/raspberrypi/linux/bl ... 8.dtsi#L16

BCM2838 has LPAE enabled , therefore all DMA addresses are 64bit.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

JGPIO
Posts: 25
Joined: Sun Feb 28, 2016 6:29 pm

Re: Rapberry pi 4 IO memory base address

Sun Nov 17, 2019 11:01 pm

Perhaps I've missed something, but is there any particular reason no one is using the bcm_host_get_peripheral_address() function?

User avatar
joan
Posts: 14376
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Rapberry pi 4 IO memory base address

Mon Nov 18, 2019 8:39 am

JGPIO wrote:
Sun Nov 17, 2019 11:01 pm
Perhaps I've missed something, but is there any particular reason no one is using the bcm_host_get_peripheral_address() function?
History. A lot of code was written and tested and debugged before that interface became available.

Utility. It didn't help with the Pi4B. As far as I am aware it was not updated for some time after the release of the Pi4B.

Portability. Does it work on all Linux distributions, does it work on 64-bit systems. If it does I might change my code to use it.

Return to “C/C++”