You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派5重启FastAPI服务器后GPIO引脚不可用(rpi-lgpio)

解决树莓派5 FastAPI重启后lgpio.error: 'GPIO not allocated'问题

问题根源

  • 全局作用域的GPIO初始化未绑定服务生命周期:FastAPI重启(尤其是自动重载模式)时,旧进程未释放GPIO资源,导致引脚被内核锁定,新进程无法重新分配。
  • RPi.GPIO并非为异步框架设计:异步环境下资源清理机制不完善,进程退出时无法自动释放GPIO。
  • 未设置进程退出钩子:服务器终止时没有主动清理GPIO资源,残留的占用状态会被内核保留,甚至重启树莓派也无法解除(部分情况下内核会保留引脚锁定状态)。

解决方案

1. 用FastAPI事件钩子管理GPIO生命周期

将GPIO的初始化和释放逻辑绑定到FastAPI的startup和shutdown事件,确保资源在服务启动时分配,终止时释放:

from typing import Union
from fastapi import FastAPI
import RPi.GPIO as GPIO

LED_PIN = 18
app = FastAPI()

@app.on_event("startup")
def init_gpio():
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(LED_PIN, GPIO.OUT)
    GPIO.output(LED_PIN, GPIO.LOW)  # 初始化引脚为低电平

@app.on_event("shutdown")
def cleanup_gpio():
    GPIO.cleanup(LED_PIN)  # 仅清理使用的引脚,避免影响其他设备
    # 若需要清理所有GPIO资源,可替换为GPIO.cleanup()

@app.get("/")
async def read_root():
    return {"Hello": "world"}

@app.get("/light-on")
async def light_on():
    GPIO.output(LED_PIN, GPIO.HIGH)
    return {"light": "on"}

@app.get("/light-off")
async def light_off():
    GPIO.output(LED_PIN, GPIO.LOW)
    return {"light": "off"}

2. 禁用FastAPI自动重载模式

调试时若使用uvicorn main:app --reload,重载会生成子进程,旧进程的GPIO占用可能残留。改用普通启动命令:

uvicorn main:app --host 0.0.0.0 --port 8000

3. 切换为异步兼容的GPIO库(推荐)

若异步环境下问题仍存在,改用官方lgpio库(对异步、多进程支持更完善):

from typing import Union
from fastapi import FastAPI
import lgpio

LED_PIN = 18
CHIP_ID = 0  # 树莓派5默认芯片ID为0,可通过`lgpio.chip_list()`查询
app = FastAPI()
gpio_handle = None

@app.on_event("startup")
def init_gpio():
    global gpio_handle
    gpio_handle = lgpio.gpiochip_open(CHIP_ID)
    lgpio.gpio_claim_output(gpio_handle, LED_PIN, 0)  # 初始状态为低电平

@app.on_event("shutdown")
def cleanup_gpio():
    global gpio_handle
    if gpio_handle:
        lgpio.gpio_free(gpio_handle, LED_PIN)
        lgpio.gpiochip_close(gpio_handle)

@app.get("/light-on")
async def light_on():
    lgpio.gpio_write(gpio_handle, LED_PIN, 1)
    return {"light": "on"}

@app.get("/light-off")
async def light_off():
    lgpio.gpio_write(gpio_handle, LED_PIN, 0)
    return {"light": "off"}

4. 应急:强制释放锁定引脚

若引脚已被锁定,可通过命令行工具强制释放:

sudo lgpio -r 18  # 释放BCM编号为18的引脚

内容的提问来源于stack exchange,提问作者Sakhile Mamba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 10:17:24