2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

備忘録 ラズパイ5 ROS2 勉強再開 ② GPIO その1 libgpiod Lチカ

Last updated at Posted at 2024-10-12

 ROS2以前の問題で、ラズパイ5で、GPIOをアクセスする方法を探ります。
 なぜって、一つは、Linux自体の変化で、

$ echo 21 > /sys/class/gpio/export

のような、sysfsを経由したGPIO操作がなくなるのです。
 もひとつの理由は、ラズパイ5で、ラズパイ4までと比べてそうとうハードが変更されて、従来のGPIOを操作するライブラリが使えなくなったことです。

環境

  • Raspberry Pi 5 8GB
  • 追加ボード;NVMe Base for Raspberry Pi 5 (NVMe Base by Pimoroni)
  • Crucial クルーシャル P2シリーズ 500GB 3D NAND NVMe PCIe M.2 SSD CT500P2SSD8
  • 初期;RaspberryPi OS Desktop 64bit (Debian version: 12 (bookworm) Release date: March 15th 2024)
  • 現在;Ubuntu Desktop 24.04LTS(64-bit)
  • ROS2;Jazzy

gpiodが残りそう

 マニュアルです。libgpiodのgpiodです??? GPIOをアクセスするライブラリlibgpiodを使うコマンドの総称がgpiodです。

 ラズパイ5で、GPIO用コマンド、Cライブラリ、Pythonライブラリのいずれにもに対応しているのがlibgpiodだけらしく、使わざるを得ません。コマンドだけならばpinctrlが対応しているようです。Pythonのライブラリはgpiozeroが対応しているのですが、単にGPIOを操作するには使いにくいです。
 ラズパイ5では/dev/gpiochip4を使うようです。
 コマンドには、gpiodetect、gpioinfo、gpioset、gpioget、gpiofind、gpiomonがあります。

$ sudo ls /dev/gpio*
/dev/gpiochip0  /dev/gpiochip2  /dev/gpiochip4  /dev/gpiomem1  /dev/gpiomem3
/dev/gpiochip1  /dev/gpiochip3  /dev/gpiomem0   /dev/gpiomem2  /dev/gpiomem4

$ sudo apt install gpiod

$ gpioinfo gpiochip4
gpiochip4 - 54 lines:
        line   0:     "ID_SDA"       unused   input  active-high
        line   1:     "ID_SCL"       unused   input  active-high
        line   2:      "GPIO2"       unused   input  active-high
        line   3:      "GPIO3"       unused   input  active-high
        line   4:      "GPIO4"       unused   input  active-high
        line   5:      "GPIO5"       unused   input  active-high
        line   6:      "GPIO6"       unused   input  active-high
        line   7:      "GPIO7"   "spi0 CS1"  output   active-low [used]
        line   8:      "GPIO8"   "spi0 CS0"  output   active-low [used]
        line   9:      "GPIO9"       unused   input  active-high
        line  10:     "GPIO10"       unused   input  active-high
        line  11:     "GPIO11"       unused   input  active-high
        line  12:     "GPIO12"       unused   input  active-high
        line  13:     "GPIO13"       unused   input  active-high
        line  14:     "GPIO14"       unused   input  active-high
        line  15:     "GPIO15"       unused   input  active-high
        line  16:     "GPIO16"       unused   input  active-high
        line  17:     "GPIO17"       unused   input  active-high
        line  18:     "GPIO18"       unused   input  active-high
        line  19:     "GPIO19"       unused   input  active-high
        line  20:     "GPIO20"       unused   input  active-high
        line  21:     "GPIO21"       unused   input  active-high
        line  22:     "GPIO22"       unused   input  active-high
        line  23:     "GPIO23"       unused   input  active-high
        line  24:     "GPIO24"       unused   input  active-high
        line  25:     "GPIO25"       unused   input  active-high
        line  26:     "GPIO26"       unused   input  active-high
        line  27:     "GPIO27"       unused   input  active-high
        line  28: "PCIE_RP1_WAKE" unused output active-high
        line  29:   "FAN_TACH"       unused   input  active-high
        line  30:   "HOST_SDA"       unused   input  active-high
        line  31:   "HOST_SCL"       unused   input  active-high
        line  32:  "ETH_RST_N"  "phy-reset"  output   active-low [used]
        line  33:          "-"       unused   input  active-high
        line  34: "CD0_IO0_MICCLK" "cam0_reg" output active-high [used]
        line  35: "CD0_IO0_MICDAT0" unused input active-high
        line  36: "RP1_PCIE_CLKREQ_N" unused input active-high
        line  37:          "-"       unused   input  active-high
        line  38:    "CD0_SDA"       unused   input  active-high
        line  39:    "CD0_SCL"       unused   input  active-high
        line  40:    "CD1_SDA"       unused   input  active-high
        line  41:    "CD1_SCL"       unused   input  active-high
        line  42: "USB_VBUS_EN" unused output active-high
        line  43:   "USB_OC_N"       unused   input  active-high
        line  44: "RP1_STAT_LED" "PWR" output active-low [used]
        line  45:    "FAN_PWM"       unused  output  active-high
        line  46: "CD1_IO0_MICCLK" "cam1_reg" output active-high [used]
        line  47:  "2712_WAKE"       unused   input  active-high
        line  48: "CD1_IO1_MICDAT1" unused input active-high
        line  49: "EN_MAX_USB_CUR" unused output active-high
        line  50:          "-"       unused   input  active-high
        line  51:          "-"       unused   input  active-high
        line  52:          "-"       unused   input  active-high
        line  53:          "-"       unused   input  active-high

 GPIOxxは、従来から使われているI/Oピンの呼び名です。このライブラリでは、GPIOxxをlinexxという呼び方をしており、Cのプログラム内ではxxと数値だけで指定するようです。

 40ピン(GPIO21)と39ピン(GND)に抵抗入りLEDをつなぎます。

$ gpioset gpiochip4 21=1

 LEDが点灯しました。
gpioinfo gpiochip4では、下記のように変化しました。

line  21:     "GPIO21"       unused  output  active-high

 消灯です。

$ gpioset gpiochip4 21=0

(参考文献) http://einstlab.web.fc2.com/RaspberryPi/5B.html

Cのライブラリ libgpiod-dev

 ドキュメントは、インストールしたら、次のディレクトリに入っています。バージョンは1.6.3でした。
/usr/share/doc/libgpiod-dev/html/index.html

 最新バージョンは2.1.2のようですが、どのOSで実装しているか不明です。1.6.3
に比べて仕様が変化しているように感じます。

$ sudo apt install libgpiod2 libgpiod-dev libgpiod-doc

$ sudo apt info libgpiod-dev
Package: libgpiod-dev
Version: 1.6.3-1.1build1

 Lチカのプログラムです。

ex401.cpp
#include <stdio.h>
#include <unistd.h>
#include <gpiod.h>
#include <error.h>

int main() {

  struct gpiod_chip *gchip;
  struct gpiod_line *glinein, *glineout;
  int value;

  // GPIOデバイスを開く
  if ((gchip = gpiod_chip_open("/dev/gpiochip4")) == NULL) {
    perror("gpiod_chip_open_lookup");
    return 1;
  }

  // GPIO出力
  // GPIOのピンのハンドラを取得する  ここではGPIO21ピンを
  if ((glineout = gpiod_chip_get_line(gchip, 21)) == NULL) {
    perror("gpiod_chip_get_line 21");
    return 1;
  }

  // GPIOを出力モードに設定する
  if (gpiod_line_request_output(glineout, "LED ON/OFF", 0) != 0) {
    perror("gpiod_line_request_output");
  }

  for (int  i=0; i < 10; i++){
    // GPIOの値を1に設定する
    if ((value = gpiod_line_set_value(glineout, 1)) == -1) {
      perror("gpiod_line_set_value");
    }
    sleep(1);

    // GPIOの値を0に設定する
    if ((value = gpiod_line_set_value(glineout, 0)) == -1) {
      perror("gpiod_line_set_value");
    }
    sleep(1);
  }

  // GPIOデバイスを閉じる
  gpiod_chip_close(gchip);
  return 0;
}

 実行します。10回、GPIO21につないだLEDが点滅します。

$ g++ ex401.cpp -lgpiod
$ ./a.out

(参考文献)

 いつものように、エラー処理を省略しました。

ex402.cpp
#include <stdio.h>
#include <unistd.h>
#include <gpiod.h>

int main() {
    struct gpiod_chip *gchip;
    struct gpiod_line *glinein, *glineout;
    // GPIOデバイスを開く
    gchip = gpiod_chip_open("/dev/gpiochip4");
    // GPIOのピンのハンドラを取得  ここではGPIO21
    glineout = gpiod_chip_get_line(gchip, 21);
    // GPIOを出力モードに設定
    gpiod_line_request_output(glineout, "LED ON/OFF", 0);

    for (int  i=0; i < 10; i++){
        gpiod_line_set_value(glineout, 1);  // GPIOの値を1に
        sleep(1);
        gpiod_line_set_value(glineout, 0);  // GPIOの値を0に
        sleep(1);
    }

    gpiod_chip_close(gchip);  // GPIOデバイスを閉じる
    return 0;
}

gpiod_chip_xxがGPIO chip operationsに分類される関数類でopen/closeにかかわります。
gpiod_line_request_xxが、Line requestsに分類される関数類で、出力、入力の設定をします。
gpiod_line_set_xxが、Reading & setting line valuesに分類される関数類で、出力、入力の値を設定をします。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?