Help us understand the problem. What is going on with this article?

C言語でRaspberry Piを操作しよう

はじめに

本記事はC言語でRaspberry Piを操作することを目的に、ライブラリの導入方法やLチカについて記載しています。

Raspberry Piで電子回路を用いた開発を行う場合はPythonによる開発が多いですが、C言語でも簡単に制御することができます。また、コンパイル言語なので実行速度が早いため、組み込みに最適です。

WiringPi

WiringPiはRaspberry Pi用のGPIOインターフェイスライブラリになります。

C言語で記述されているため、BCM2835、BCM2836、およびBCM2837 SoCデバイス用で使用できます。

WiringPiの導入

WiringPiの導入方法はパッケージインストールか、ソースからインストールすることで導入できます。

なお、ソースインストールは初心者にはライブラリの依存関係の理解が必要になってくるため、パッケージインストールをおすすめします。どうしても最新のバージョンを使用したい場合はソースからインストールしてください。

パッケージインストールは以下のコマンドでインストールできます。

  • インストール
    $ sudo apt --purge remove wiringpi
  • パッケージの確認
    $ dpkg -l | grep wiringpi
ii  wiringpi                              2.46                              armhf        Raspberry Pi GPIO libraries, headers and gpio command

ソースでインストールする場合は以下のコマンドを実行して、最新のソースをダウンロードします。

  • ソースのダウンロード
    $ wget https://project-downloads.drogon.net/wiringpi-latest.deb
  • ソースのインストール
    $ sudo dpkg -i wiringpi-latest.deb

C言語でLチカ

電子回路図

Fritzingで作成した画像を例に解説します。

本記事ではGPIO制御するためにRaspberry Pi側はGPIOの端子番号7を入力に使用しています。LEDは端子の長いアノード側を電源の+側に接続し、端子の短いカソード側を抵抗と接続します。抵抗は100Ωを使用しています。

Lチカ_ブレッドボード.png

実装

Blinkを参考に、以下のblink.cファイルを作成します。

本記事の環境では利用するGPO端子の番号として7を使用しています。

  • blink.c
#include <wiringPi.h>
#define pin 7 
int main (void)
{
  wiringPiSetup () ;
  pinMode (pin, OUTPUT) ;
  for (;;)
  {
    digitalWrite (pin, HIGH) ; delay (500) ;
    digitalWrite (pin,  LOW) ; delay (500) ;
  }
  return 0 ;
}

blink.cファイル作成後、以下のコマンを実行し、コンパイルを行います。

$ gcc -Wall -o blink blink.c -lwiringPi

コンパイルを実行すると実行形式ファイルが作成されます。
以下のコマンドを実行し、Lチカを行います。0.5秒毎に点灯します。

$ ./blink

写真 2020-05-17 23 18 33.jpg

コンパイルエラー

ソースからのインストールの場合、コンパイル実行時に以下の様なエラーが発生する場合があります。以下の場合はリンク時にエラーが発生していて、fcntlという関数が見当たらないというエラーになります。

調査方法について解説します。

/usr/lib/gcc/arm-linux-gnueabihf/6/../../../libwiringPi.so: `fcntl@GLIBC_2.28' に対する定義されていない参照です
collect2: error: ld returned 1 exit status

まずはfindコマンドなどで、libwiringPi.soファイルを検索します。

$ find / -name libwiringPi.so

ファイルのパスが判明したらlddコマンドでリンクを確認します。

  • ldd
    $ ldd /usr/lib/libwiringPi.so
/usr/lib/libwiringPi.so: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.28' not found (required by /usr/lib/libwiringPi.so)
    linux-vdso.so.1 (0x7eff4000)
    /usr/lib/arm-linux-gnueabihf/libarmmem.so (0x76f5c000)
    libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76ec9000)
    libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76ea0000)
    librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76e89000)
    libcrypt.so.1 => /lib/arm-linux-gnueabihf/libcrypt.so.1 (0x76e4a000)
    libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76d0b000)
    /lib/ld-linux-armhf.so.3 (0x76f90000)

コマンド実行結果からlibc.so.6ファルがglibcバージョン2.28に対してコンパイルされていることが分かります。実行するにはそのバージョンが必要ですが、古いバージョンがインストールされていると考えられるため、現在のglibcのバージョンに対してプログラムを再コンパイルするか、新しいバージョンのglibcをインストールする必要があります。

objdumpコマンドはコンパイルエラーなどの調査で重宝します。
コマンドを実行すると、オブジェクトファイルの情報を出力します。

  • ダンプ
    $ objdump -T /lib/arm-linux-gnueabihf/libc.so.6

/lib/arm-linux-gnueabihf/libc.so.6:     ファイル形式 elf32-littlearm

DYNAMIC SYMBOL TABLE:
00015fe0 l    d  .text  00000000              .text
00139710 l    d  .tdata 00000000              .tdata
00000000      DO *UND*  00000000  GLIBC_PRIVATE _rtld_global
00000000      DO *UND*  00000000  GLIBC_PRIVATE __libc_enable_secure
00000000      DF *UND*  00000000  GLIBC_2.4   __tls_get_addr
00000000      DO *UND*  00000000  GLIBC_PRIVATE _rtld_global_ro
00000000      DO *UND*  00000000  GLIBC_PRIVATE __pointer_chk_guard
00000000      DF *UND*  00000000  GLIBC_PRIVATE _dl_find_dso_for_object
00000000  w   D  *UND*  00000000              _dl_starting_up
00000000      DO *UND*  00000000  GLIBC_PRIVATE _dl_argv
0005f848 g    DF .text  000001c0  GLIBC_2.4   putwchar
000e1994 g    DF .text  00000014  GLIBC_2.4   __gethostname_chk
0007daec g    DF .text  00000030 (GLIBC_2.4)  __strspn_c1
0007db1c g    DF .text  00000040 (GLIBC_2.4)  __strspn_c2
00016a2c g    DF .text  00000024  GLIBC_2.4   __aeabi_MB_CUR_MAX
000f9614 g    DF .text  00000104  GLIBC_2.4   setrpcent

おわりに

LED1本光らすだけでも何かの通知に利用したり色々応用ができます。
Raspberry PiはC言語の勉強にも最適ですね。

Brutus
DevOpsとAIの二刀流を目指す凡人。Python、RaspberryPi、Linux、Docker、k8s、セキュリティ、Oracle Cloud、Terraform、Ansible等について発信しています。登壇、執筆等あれば、Twitterよりメッセージお願いします。
https://brutus.ml/
gauss
株式会社GAUSSは、AIソフトウェアを組み込んだサーバの提供、AIサービス構築のコンサルティング、AIのエンジニア育成をセットにしてサービス提供を展開するスタートアップ企業です。
https://gauss-ai.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした