Skip to main content

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

Metadata

Release files for bcmio 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bcmio 1.1.2
File Size Uploaded Provenance
bcmio-1.1.2.tar.gz 21.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bcmio 1.1.2
File Interpreter ABI Platform
bcmio-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 45.0 kB

Release files / bcmio-1.1.2.tar.gz

Download URL bcmio-1.1.2.tar.gz
Size 21.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f125a3583ea5be0a94a134873993a3f3a9dae5f9b984bcf0f1b63b7679c3d25a
BLAKE2b-256 checksum
How to use checksums
ae39c021df0d67890a568f32a937d636941587b17cf1e5fcea06813058552ecc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / bcmio-1.1.2-py3-none-any.whl

Download URL bcmio-1.1.2-py3-none-any.whl
Size 23.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
02fcd7107a3ae1ba0111e1875e3a589dbe1122c1e305f8f843a071de67d1f1a9
BLAKE2b-256 checksum
How to use checksums
e68f8b18b3e4ee22e1546e9b4e8b9b0c078f91ca3517b7a5982c4245d0efd0e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for bcmio 1.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page