Raspberry Pi Hardware - bogics/rpi_gpio_driver GitHub Wiki

Literature:

 

System on Chip (SoC)

This GPIO driver is developed and tested on Raspberry Pi Model B+, which is based on the BCM2835 SoC.
However, it should work on all other Rapsberry Pi models.

  • BCM2835 SoC is used in the Raspberry Pi Model A, B, B+, the Compute Module, and the Raspberry Pi Zero.
  • BCM2836 SoC is used in the Raspberry Pi 2 Model B, but the underlying architecture is identical to BCM2835.
    The only significant difference is the removal of the ARM1176JZF-S processor and replacement with a quad-core Cortex-A7 cluster.
  • BCM2837 SoC is used in the Raspberry Pi 3, and in later models of the Raspberry Pi 2. The underlying architecture is identical to the BCM2836.
    The only significant difference is the replacement of the ARMv7 quad core cluster with a quad-core ARM Cortex A53 (ARMv8) cluster.

Hardware details can be obtained with cat /proc/cpuinfo.
Among the other information, Hardware and Revision are displayed, e.g:
Hardware : BCM2708
Revision : 0010

Take a look at RPi_HardwareHistory for more details about the board Revision.

 

BCM2835 GPIO

BCM2835 has 54 general-purpose I/O (GPIO) lines. Only subset of them are exposed to the external connector:
gpio connector

There are 41 32-bit GPIO registers. Take a look at Chapter 6 General Purpose I/O (GPIO) of the BCM2835-ARM-Peripherals for details.

According to the memory map diagram on page 5 in the BCM2835-ARM-Peripherals, there are three address types:
1. ARM virtual addresses
The kernel is configured for a 1GB/3GB split between kernel and user-space memory.

  • Virtual addresses in kernel mode will range between 0xC0000000 and 0xEFFFFFFF
  • Virtual addresses in user mode will range between 0x00000000 and 0xBFFFFFFF

2. ARM physical addresses
Physical addresses start at 0x00000000.

3. Bus addresses
The peripheral addresses specified into the BCM2835-ARM-Peripherals document are bus addresses!
Software directly accessing peripherals must translate these addresses into the physical or virtual addresses.
Software accessing peripherals using the DMA engines must use bus addresses.
Software accessing RAM directly must use physical addresses (based at 0x00000000).
Software accessing RAM using the DMA engines must use bus addresses (based at 0xC0000000).

The peripherals bus addresses start at 0x7E000000. According to the memory map diagram, peripheral bus address 0x7Ennnnnn is available:

  • at physical address 0x20nnnnnn
  • at virtual address in kenel-mode 0xF2nnnnn

 

BCM2708 vs BCM2835

There is some confusion related to the SoC naming. It is sometimes referred to as bcm2708, but sometimes to bcm2835. See discussion about this here.

Technically 2708 is the family, and 2835 is a specific implementation. We now know that 2835 is the only implementation in the family that can run linux.

 

Although it is beyond the scope of this project, it is interesting to see how the kernel is configured regarding the SoC:
Kernel Raspberry Pi Model B+ is configured with bcmrpi_defconfig, look here for more details about configuring and building kernel for Raspberry Pi.
Then, enter make menuconfig and search for the ARCH_BCM, ARCH_BCM2835 and ARCH_BCM2708:

  │ Symbol: ARCH_BCM [=n]                       
  │ Type  : boolean                             
  │ Prompt: Broadcom SoC Support                
  │   Location:                                 
  │ (1) -> System Type                          
  │   Defined at arch/arm/mach-bcm/Kconfig:1 

  │ Symbol: ARCH_BCM2835 [=n]                  
  │ Type  : boolean                             
  │ Prompt: Broadcom BCM2835 family             
  │   Location:                                 
  │ (1) -> System Type                          
  │       -> Broadcom SoC Support (ARCH_BCM [=n]) 
  │   Defined at arch/arm/mach-bcm/Kconfig:124    
  │   Depends on: ARCH_BCM [=n]                   
  
  │ Symbol: ARCH_BCM2708 [=y]                     
  │ Type  : boolean                               
  │ Prompt: Broadcom BCM2708 family               
  │   Location:                                   
  │     -> System Type                            
  │ (1)   -> ARM system type (<choice> [=y])      
  │   Defined at arch/arm/Kconfig:320             

It can be expected that ARCH_BCM2708 [=y], but ARCH_BCM [=n] and ARCH_BCM2835 [=n] are somehow surprisingly.
ARCH_BCM and ARCH_BCM2835 are even not visible in the menu.
To find the answers, take a look at the arch/arm/mach-bcm/Kconfig snippet:

menuconfig ARCH_BCM
	bool "Broadcom SoC Support" if ARCH_MULTI_V6_V7
	help
	  This enables support for Broadcom ARM based SoC chips

if ARCH_BCM
...
config ARCH_BCM2835
	bool "Broadcom BCM2835 family" if ARCH_MULTI_V6
...

We can see that the ARCH_BCM depends on the ARCH_MULTI_V6_V7.
Further, in the arch/arm/Kconfig we can see that ARCH_MULTI_V6_V7 depends on the ARCH_MULTIPLATFORM.
ARCH_MULTIPLATFORM can be selected from System Type -> ARM system type, but the Broadcom BCM2708 family (CONFIG_ARCH_BCM2708) is already selected there!

It turns out that the CONFIG_ARCH_BCM2708 and the ARCH_BCM2835 are mutually exclusive!
If the ARCH_MULTIPLATFORM is selected instead of the CONFIG_ARCH_BCM2708 in ARM system type menu,
[ ] Broadcom SoC Support (NEW) ---- will show up, but without the Broadcom BCM2835 family entry.
So, enable also the ARCH_MULTI_V6, which is dependency for the ARCH_BCM2835 as we have previously seen:
System Type -> Multiple platform selection, select the ARMv6 based platforms (ARM11) too:
*** CPU Core family selection ***
[*] ARMv6 based platforms (ARM11) (NEW)
[*] ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait) (NEW)

Go back to the [*] Broadcom SoC Support ---> and CONFIG_ARCH_BCM2835 can finally be selected:
*** Other Architectures ***
[*] Broadcom BCM2835 family
Help for the [*] Broadcom BCM2835 family from make menuconfig displays:

  │ CONFIG_ARCH_BCM2835:                                            
  │                                                                 
  │ This enables support for the Broadcom BCM2835 SoC. This SoC is  
  │ used in the Raspberry Pi and Roku 2 devices.                    
  │                                                                 
  │ Symbol: ARCH_BCM2835 [=y]                                       
  │ Type  : boolean                                                 
  │ Prompt: Broadcom BCM2835 family                                 
  │   Location:                                                     
  │     -> System Type                                              
  │       -> Broadcom SoC Support (ARCH_BCM [=y]) 

According to the previously exposed, if the multiple platforms are allowed into the ARM system type instead of the BCM2708 family, Multiple platform selection menu will be unlocked with option to enable the ARMv6 based platforms (ARM11).
If the ARM11 is enabled, then Broadcom BCM2835 family should be selected from the Broadcom SoC Support.
ARMv6 based platforms (ARM11) perfectly fits to the 700 MHz ARM11 ARM1176JZF-S core CPU of the Model B+.
This configuration seems to be correct for me, but I have not tested it yet!
Anyway, stick with the working one :)

⚠️ **GitHub.com Fallback** ⚠️