あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

Raspberry Pi OSのsysfsによるGPIOは非推奨になった話

今朝、社のSlackに貼られた日経の記事で、Pi 5でGPIOがRP1経由になった影響でsysfsでのGPIO番号が変わったという話題を見ました。

xtech.nikkei.com

ほんまかいなと思って試すと、確かにGPIOの番号がいろいろ違っていました。っていうか、他のデバイスのGPIOも見れるんですね。これはこれで活用できそう。さておき、長いけどぜんぶ貼っておきます。

$ cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 512-543, parent: platform/107d508500.gpio, gpio-brcmstb@107d508500:
 gpio-512 (-                   )
 gpio-513 (2712_BOOT_CS_N      |spi10 CS0           ) out hi ACTIVE LOW
 gpio-514 (2712_BOOT_MISO      )
 gpio-515 (2712_BOOT_MOSI      )
 gpio-516 (2712_BOOT_SCLK      )
 gpio-517 (-                   )
 gpio-518 (-                   )
 gpio-519 (-                   )
 gpio-520 (-                   )
 gpio-521 (-                   )
 gpio-522 (-                   )
 gpio-523 (-                   )
 gpio-524 (-                   )
 gpio-525 (-                   )
 gpio-526 (PCIE_SDA            )
 gpio-527 (PCIE_SCL            )
 gpio-528 (-                   )
 gpio-529 (-                   )
 gpio-530 (-                   )
 gpio-531 (-                   )
 gpio-532 (PWR_GPIO            |pwr_button          ) in  hi ACTIVE LOW
 gpio-533 (2712_G21_FS         )
 gpio-534 (-                   )
 gpio-535 (-                   )
 gpio-536 (BT_RTS              )
 gpio-537 (BT_CTS              )
 gpio-538 (BT_TXD              )
 gpio-539 (BT_RXD              )
 gpio-540 (WL_ON               |wl_on_reg           ) out hi 
 gpio-541 (BT_ON               |shutdown            ) out hi 
 gpio-542 (WIFI_SDIO_CLK       )
 gpio-543 (WIFI_SDIO_CMD       )

gpiochip1: GPIOs 544-547, parent: platform/107d508500.gpio, gpio-brcmstb@107d508520:
 gpio-544 (WIFI_SDIO_D0        )
 gpio-545 (WIFI_SDIO_D1        )
 gpio-546 (WIFI_SDIO_D2        )
 gpio-547 (WIFI_SDIO_D3        )

gpiochip2: GPIOs 548-564, parent: platform/107d517c00.gpio, gpio-brcmstb@107d517c00:
 gpio-548 (RP1_SDA             )
 gpio-549 (RP1_SCL             )
 gpio-550 (RP1_RUN             |RP1 RUN pin         ) out hi 
 gpio-551 (SD_IOVDD_SEL        |vdd-sd-io           ) out lo 
 gpio-552 (SD_PWR_ON           |sd_vcc_reg          ) out lo 
 gpio-553 (SD_CDET_N           |cd                  ) in  hi ACTIVE LOW
 gpio-554 (SD_FLG_N            )
 gpio-555 (-                   )
 gpio-556 (2712_WAKE           )
 gpio-557 (2712_STAT_LED       |ACT                 ) out hi ACTIVE LOW
 gpio-558 (-                   )
 gpio-559 (-                   )
 gpio-560 (PMIC_INT            )
 gpio-561 (UART_TX_FS          )
 gpio-562 (UART_RX_FS          )
 gpio-563 (-                   )
 gpio-564 (-                   )

gpiochip3: GPIOs 565-570, parent: platform/107d517c00.gpio, gpio-brcmstb@107d517c20:
 gpio-565 (HDMI0_SCL           )
 gpio-566 (HDMI0_SDA           )
 gpio-567 (HDMI1_SCL           )
 gpio-568 (HDMI1_SDA           )
 gpio-569 (PMIC_SCL            )
 gpio-570 (PMIC_SDA            )

gpiochip4: GPIOs 571-624, parent: platform/1f000d0000.gpio, pinctrl-rp1:
 gpio-571 (ID_SDA              )
 gpio-572 (ID_SCL              )
 gpio-573 (GPIO2               )
 gpio-574 (GPIO3               )
 gpio-575 (GPIO4               )
 gpio-576 (GPIO5               )
 gpio-577 (GPIO6               )
 gpio-578 (GPIO7               )
 gpio-579 (GPIO8               )
 gpio-580 (GPIO9               )
 gpio-581 (GPIO10              )
 gpio-582 (GPIO11              )
 gpio-583 (GPIO12              )
 gpio-584 (GPIO13              )
 gpio-585 (GPIO14              )
 gpio-586 (GPIO15              )
 gpio-587 (GPIO16              )
 gpio-588 (GPIO17              )
 gpio-589 (GPIO18              )
 gpio-590 (GPIO19              )
 gpio-591 (GPIO20              )
 gpio-592 (GPIO21              )
 gpio-593 (GPIO22              )
 gpio-594 (GPIO23              )
 gpio-595 (GPIO24              )
 gpio-596 (GPIO25              )
 gpio-597 (GPIO26              )
 gpio-598 (GPIO27              )
 gpio-599 (PCIE_RP1_WAKE       )
 gpio-600 (FAN_TACH            )
 gpio-601 (HOST_SDA            )
 gpio-602 (HOST_SCL            )
 gpio-603 (ETH_RST_N           |phy-reset           ) out hi ACTIVE LOW
 gpio-604 (-                   )
 gpio-605 (CD0_IO0_MICCLK      |cam0_reg            ) out lo 
 gpio-606 (CD0_IO0_MICDAT0     )
 gpio-607 (RP1_PCIE_CLKREQ_N   )
 gpio-608 (-                   )
 gpio-609 (CD0_SDA             )
 gpio-610 (CD0_SCL             )
 gpio-611 (CD1_SDA             )
 gpio-612 (CD1_SCL             )
 gpio-613 (USB_VBUS_EN         )
 gpio-614 (USB_OC_N            )
 gpio-615 (RP1_STAT_LED        |PWR                 ) out hi ACTIVE LOW
 gpio-616 (FAN_PWM             )
 gpio-617 (CD1_IO0_MICCLK      |cam1_reg            ) out lo 
 gpio-618 (2712_WAKE           )
 gpio-619 (CD1_IO1_MICDAT1     )
 gpio-620 (EN_MAX_USB_CUR      )
 gpio-621 (-                   )
 gpio-622 (-                   )
 gpio-623 (-                   )
 gpio-624 (-                   )

ここまでスクロールしてくれてありがとうございました。

で、これをPi 4でも実行したら、こっちも違うじゃないですか。なんで?

$ cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 512-569, parent: platform/fe200000.gpio, pinctrl-bcm2711:
 gpio-512 (ID_SDA              )
 gpio-513 (ID_SCL              )
 gpio-514 (GPIO2               )
 gpio-515 (GPIO3               )
 gpio-516 (GPIO4               )
 gpio-517 (GPIO5               )
 gpio-518 (GPIO6               )
 gpio-519 (GPIO7               |spi0 CS1            ) out hi ACTIVE LOW
 gpio-520 (GPIO8               |spi0 CS0            ) out hi ACTIVE LOW
 gpio-521 (GPIO9               )
 gpio-522 (GPIO10              )
 gpio-523 (GPIO11              )
 gpio-524 (GPIO12              )
 gpio-525 (GPIO13              )
 gpio-526 (GPIO14              )
 gpio-527 (GPIO15              )
 gpio-528 (GPIO16              )
 gpio-529 (GPIO17              )
 gpio-530 (GPIO18              )
 gpio-531 (GPIO19              )
 gpio-532 (GPIO20              )
 gpio-533 (GPIO21              )
 gpio-534 (GPIO22              )
 gpio-535 (GPIO23              )
 gpio-536 (GPIO24              )
 gpio-537 (GPIO25              )
 gpio-538 (GPIO26              )
 gpio-539 (GPIO27              )
 gpio-540 (RGMII_MDIO          )
 gpio-541 (RGMIO_MDC           )
 gpio-542 (CTS0                )
 gpio-543 (RTS0                )
 gpio-544 (TXD0                )
 gpio-545 (RXD0                )
 gpio-546 (SD1_CLK             )
 gpio-547 (SD1_CMD             )
 gpio-548 (SD1_DATA0           )
 gpio-549 (SD1_DATA1           )
 gpio-550 (SD1_DATA2           )
 gpio-551 (SD1_DATA3           )
 gpio-552 (PWM0_MISO           )
 gpio-553 (PWM1_MOSI           )
 gpio-554 (STATUS_LED_G_CLK    |ACT                 ) out lo 
 gpio-555 (SPIFLASH_CE_N       )
 gpio-556 (SDA0                )
 gpio-557 (SCL0                )
 gpio-558 (RGMII_RXCLK         )
 gpio-559 (RGMII_RXCTL         )
 gpio-560 (RGMII_RXD0          )
 gpio-561 (RGMII_RXD1          )
 gpio-562 (RGMII_RXD2          )
 gpio-563 (RGMII_RXD3          )
 gpio-564 (RGMII_TXCLK         )
 gpio-565 (RGMII_TXCTL         )
 gpio-566 (RGMII_TXD0          )
 gpio-567 (RGMII_TXD1          )
 gpio-568 (RGMII_TXD2          )
 gpio-569 (RGMII_TXD3          )

gpiochip1: GPIOs 570-577, parent: platform/soc:firmware:gpio, raspberrypi-exp-gpio, can sleep:
 gpio-570 (BT_ON               |shutdown            ) out hi 
 gpio-571 (WL_ON               )
 gpio-572 (PWR_LED_OFF         |PWR                 ) out lo ACTIVE LOW
 gpio-573 (GLOBAL_RESET        )
 gpio-574 (VDD_SD_IO_SEL       |vdd-sd-io           ) out lo 
 gpio-575 (CAM_GPIO            |cam1_regulator      ) out lo 
 gpio-576 (SD_PWR_ON           |regulator-sd-vcc    ) out lo 
 gpio-577 (SD_OC_N             )

Pi 4でも、古いOSではsysfsの番号がGPIOピン番号と一致するようです。

$ sudo cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-57, parent: platform/fe200000.gpio, pinctrl-bcm2711:
 gpio-0   (ID_SDA              )
 gpio-1   (ID_SCL              )
 gpio-2   (SDA1                )
 gpio-3   (SCL1                )
 gpio-4   (GPIO_GCLK           )
 gpio-5   (GPIO5               )
 gpio-6   (GPIO6               )
 gpio-7   (SPI_CE1_N           )
 gpio-8   (SPI_CE0_N           )
 gpio-9   (SPI_MISO            )
 gpio-10  (SPI_MOSI            |i2c@0               ) out lo 
 gpio-11  (SPI_SCLK            |i2c@0               ) out lo 
 gpio-12  (GPIO12              )
 gpio-13  (GPIO13              )
 gpio-14  (TXD1                )
 gpio-15  (RXD1                )
 gpio-16  (GPIO16              )
 gpio-17  (GPIO17              )
 gpio-18  (GPIO18              |spi7 CS0            ) out hi ACTIVE LOW
 gpio-19  (GPIO19              |backlight           ) out hi 
 gpio-20  (GPIO20              )
 gpio-21  (GPIO21              )
 gpio-22  (GPIO22              )
 gpio-23  (GPIO23              )
 gpio-24  (GPIO24              )
 gpio-25  (GPIO25              )
 gpio-26  (GPIO26              |mosi                ) out hi 
 gpio-27  (GPIO27              |sck                 ) in  hi 
 gpio-28  (RGMII_MDIO          )
 gpio-29  (RGMIO_MDC           )
 gpio-30  (CTS0                )
 gpio-31  (RTS0                )
 gpio-32  (TXD0                )
 gpio-33  (RXD0                )
 gpio-34  (SD1_CLK             )
 gpio-35  (SD1_CMD             )
 gpio-36  (SD1_DATA0           )
 gpio-37  (SD1_DATA1           )
 gpio-38  (SD1_DATA2           )
 gpio-39  (SD1_DATA3           )
 gpio-40  (PWM0_MISO           )
 gpio-41  (PWM1_MOSI           )
 gpio-42  (STATUS_LED_G_CLK    |ACT                 ) out lo 
 gpio-43  (SPIFLASH_CE_N       )
 gpio-44  (SDA0                )
 gpio-45  (SCL0                )
 gpio-46  (RGMII_RXCLK         )
 gpio-47  (RGMII_RXCTL         )
 gpio-48  (RGMII_RXD0          )
 gpio-49  (RGMII_RXD1          )
 gpio-50  (RGMII_RXD2          )
 gpio-51  (RGMII_RXD3          )
 gpio-52  (RGMII_TXCLK         )
 gpio-53  (RGMII_TXCTL         )
 gpio-54  (RGMII_TXD0          )
 gpio-55  (RGMII_TXD1          )
 gpio-56  (RGMII_TXD2          )
 gpio-57  (RGMII_TXD3          )

gpiochip1: GPIOs 504-511, parent: platform/soc:firmware:gpio, raspberrypi-exp-gpio, can sleep:
 gpio-504 (BT_ON               )
 gpio-505 (WL_ON               )
 gpio-506 (PWR_LED_OFF         |PWR                 ) out lo ACTIVE LOW
 gpio-507 (GLOBAL_RESET        )
 gpio-508 (VDD_SD_IO_SEL       |vdd-sd-io           ) out lo 
 gpio-509 (CAM_GPIO            |cam1_regulator      ) out lo 
 gpio-510 (SD_PWR_ON           |sd_vcc_reg          ) out lo 
 gpio-511 (SD_OC_N             )

調べた

フォーラムで言及されてました。

https://forums.raspberrypi.com/viewtopic.php?p=2165403&sid=09f001c95deee231b3ecb0c2da29cae4#p2165403

For years now, fixing the base GPIO number to zero has been frowned upon by the kernel devs. In the next kernels we release (6.6) there will be an error message at boot up about it. At the same time, the sysfs interface to the GPIOs has been deprecated - some distributions have already disabled it and are expecting users to go through libgpiod.
The launch of Pi 5 gave us the opportunity to nudge people to update their apps in preparation for the upcoming changes without breaking existing systems. When we launch 6.6 the older Pis will have the same, high-numbered GPIOsn - probably still available by sysfs, but eventually that will be switched off.

曰く、ここ数年、ベースのGPIO番号を固定するのはカーネル開発者から嫌がられていたそうで、Pi 5のリリースの機会に合わせて固定をやめたため、番号が固定ではなくなったようでした。さらに、RPi OSのカーネル6.6からは過去のモデルでも固定を廃止かつ非推奨化していて、最終的にはsysfsからのアクセスは廃止?(switch off)されるようです。つまり、Pi 5はきっかけではあるものの、Linuxの標準に合わせていく都合で固定がなくなっているということのようです。なお、カーネル6.6の起動時のエラーメッセージというのは確認できませんでした。

先月リリースのBookwormの最新版にはもうカーネル6.6がバンドルされているので、Bookwormを新規インストールするか、Bookworm環境のアップデートを実行すると、sysfsでのGPIO操作は壊れることになりそうです。日経の記事もsysfsの廃止には触れていたものの、カーネル6.6と過去モデルへの波及は触れられていなかったので、どこを参照したのかは不明ですが、まあsysfsは卒業したほうが良いのは間違いないようでした。

有志がエミュレートするツールを作成したそうなので、そう言うのを使うのも延命策としてはあるみたいです。

https://forums.raspberrypi.com/viewtopic.php?t=367548

自宅の環境だとカーテンEjectがsysfsを使っていた気がするので、Bookwormにするときは気をつけないといけない、というか、GPIO周りはぜんぶ見直しって感じがしますね。Pimoroniも製品用のライブラリのアップデートに結構苦労しているようなので、Bookwormで始まったGPIO移行まわりは大変そうだなあという印象です。

ちなみに、sysfsのGPIOについては別のスレッドでも発言されていた模様。

https://forums.raspberrypi.com/viewtopic.php?p=2160793#p2160793
https://forums.raspberrypi.com/viewtopic.php?p=2160806#p2160806

OSでガラッと変わるときは移行ガイドみたいなのもあると良いのかもですねえ。カメラのときもディスプレイのkms周りのときもそうでしたけど……。