Skip to main content

Low-level GPIO library for Raspberry Pi 4 (BCM2711) using /dev/mem + mmap

Project description

bcmio

Biblioteca Python low-level para controle de GPIO do Raspberry Pi 4 Model B (BCM2711) usando acesso direto a registradores via mmap e /dev/mem (MMIO).

Aviso: acessar /dev/mem normalmente requer root (sudo). Use com cuidado: MMIO incorreto pode travar o sistema.

Objetivos

  • Performance: escrita/leitura direto em registradores (GPSET/GPCLR/GPLEV)
  • Arquitetura modular: separar low-level (MMIO/registradores) e high-level (abstrações)
  • API familiar (inspirada em RPi.GPIO/pigpio/gpiozero), mas sem dependências dessas bibliotecas
  • Código tipado, com docstrings, pronto para evoluir para PWM/SPI/I2C/UART/interrupts/DMA

Arquitetura (módulos)

  • bcmio/memory.py: abertura de /dev/mem, mmap, leitura/escrita 32-bit
  • bcmio/constants.py: offsets e constantes (GPIO modes, pulls, endereços base)
  • bcmio/gpio.py: acesso aos registradores GPIO (FSEL, SET/CLR, LEV, PULL)
  • bcmio/pin.py: classe Pin (alto nível) para um pino individual
  • bcmio/exceptions.py: exceções customizadas
  • bcmio/utils.py: helpers (validação, bit operations)
  • bcmio/pwm.py, bcmio/interrupts.py: placeholders para evolução

Como mmap funciona (visão geral)

  1. Abrimos /dev/mem (arquivo especial que expõe memória física do SoC).
  2. Fazemos mmap de uma página (ou mais) a partir do endereço físico dos periféricos GPIO.
  3. A partir do ponteiro mapeado, fazemos leituras/escritas de 32 bits em offsets específicos.

No Linux, isso é MMIO (Memory Mapped I/O): escrever em um registrador mapeado altera o hardware.

Endereços base (BCM2711)

O datasheet usa endereços no barramento (bus) como 0x7E200000 para o bloco GPIO. No Raspberry Pi 4, o endereço físico tipicamente é 0xFE200000 (peripheral base 0xFE000000 + GPIO offset 0x200000).

Esta biblioteca:

  • expõe ambos em bcmio.constants (GPIO_BASE_BUS, GPIO_BASE_PHYS_DEFAULT)
  • por padrão usa o físico (0xFE200000)
  • permite sobrescrever o endereço base via GPIO.open(base_phys=...)

Registradores GPIO usados (BCM2711)

Offsets relativos ao base do GPIO (bloco GPIO):

  • GPFSEL0..5 (Function Select): 3 bits por pino para definir IN, OUT, ou função alternativa
  • GPSET0..1 (Set): escrever 1 no bit seta o pino em nível alto (atômico)
  • GPCLR0..1 (Clear): escrever 1 no bit seta o pino em nível baixo (atômico)
  • GPLEV0..1 (Level): lê o nível atual do pino
  • GPIO_PUP_PDN_CNTRL_REG0..3: 2 bits por pino para pull-up/pull-down/no-pull (BCM2711)

Uso

API estilo “módulo” (GPIO)

from bcmio import GPIO

GPIO.safe_shutdown_enable()        # opcional: cleanup automático em SIGINT/SIGTERM/exit
GPIO.open()                       # inicializa /dev/mem + mmap
GPIO.setup(17, GPIO.OUT, pull=GPIO.PULL_NONE)
GPIO.write(17, GPIO.HIGH)
value = GPIO.read(17)
GPIO.cleanup()

Context manager (shutdown seguro)

from bcmio import GPIO

GPIO.safe_shutdown_enable()

with GPIO() as gpio:
    gpio.setup(17, gpio.OUT)
    gpio.write(17, gpio.HIGH)

API orientada a objeto (Pin)

from bcmio import Pin

led = Pin(17, mode=Pin.OUT)
led.high()
led.low()
led.toggle()
led.close()

Exemplos

Veja exemplos/:

  • exemplos/blink.py
  • exemplos/blink_safe.py
  • exemplos/button_read.py
  • exemplos/button_safe.py
  • exemplos/toggle.py
  • exemplos/read_digital.py

Também há uma pasta examples/ (API high-level e eventos):

  • examples/blink.py
  • examples/button.py
  • examples/pwm_led.py
  • examples/interrupt_button.py
  • examples/servo_control.py
  • examples/safe_shutdown.py

Testes

Os testes em testes/ não acessam /dev/mem. Eles usam um backend fake de memória para validar:

  • cálculo de offsets e bitfields de GPFSEL
  • GPSET/GPCLR e leitura em GPLEV
  • configuração de pull em GPIO_PUP_PDN_CNTRL_REGx

Rodar:

python -m pip install -e ".[dev]"
pytest -q

Segurança e boas práticas

  • Use sudo apenas quando necessário.
  • Prefira isolar e revisar o endereço base antes de usar em produção.
  • Em produção, considere um modo “safe” ou /dev/gpiomem (não implementado aqui por requisito).
  • Se estiver usando PWM/eventos, evite apertar Ctrl+C repetidamente; GPIO.safe_shutdown_enable() já executa cleanup().

Safety limit (GPIO 0–27)

Por padrão, bcmio bloqueia pinos acima de GPIO27 para reduzir riscos em hardware real. Se você precisar acessar GPIOs além disso, ajuste a validação no seu código (API para override planejada).

Backends

  • GPIO.set_backend("mmio"): usa /dev/mem + mmap (default)
  • GPIO.set_backend("mock"): registradores em memória (testes/CI)

Eventos por hardware (edge detect)

Para um sistema event-driven sem polling de GPLEV, use:

from bcmio import GPIO

GPIO.safe_shutdown_enable()
GPIO.open()
GPIO.setup(27, GPIO.IN, pull=GPIO.PULL_UP)

def cb(pin: int) -> None:
    print("edge event on", pin)

GPIO.add_event_detect(27, GPIO.FALLING, cb)  # GPEDS/GPFEN/GPREN

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bcmio-1.1.1.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bcmio-1.1.1-py3-none-any.whl (23.0 kB view details)

Uploaded Python 3

File details

Details for the file bcmio-1.1.1.tar.gz.

File metadata

  • Download URL: bcmio-1.1.1.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for bcmio-1.1.1.tar.gz
Algorithm Hash digest
SHA256 22950c3eae61376dbdadf3aefe4bf13344c9f8470a548b09e88e20483d963279
MD5 03a1a6d7cdb1b4b8afe30cbefeac63c0
BLAKE2b-256 89dce86a7e5b1502f6c6de7ae89273c1f796148994995dde6354daebc12362c7

See more details on using hashes here.

File details

Details for the file bcmio-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: bcmio-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 23.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for bcmio-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 833e50b4163f28d5f8953a178d230dfd5948e4555ce84dafc9ac7b1598ec0547
MD5 d14f8d0700f56afd90d2c0d0273f3b41
BLAKE2b-256 1dc65bbeebc266500bc9d32ad2b91088e7180f837d453de5f201dc2efe78f0be

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page