*[[CentOSからI/Oをアクセス]] [#td1aabbe] **はじめに [#d7ab3939] > >Raspberry Pi 3にCentOS7をインストールした場合のI/Oへのアクセス方法をまとめました。~ Rasbianでは、各種の方法が提供されているようですが、CentOSの対応状況が不明です。~ そのため、調べた結果をメモします。 < **デバイスツリーサポート状況 [#da29060d] ***デバイスツリー(Device Tree)とは [#bbe1a485] > >聞き慣れない用語ですが、I/Oアクセスに関する記事を検索すると、よく見かけます。~ 結局のところ、ARM Linux 用のプロパティ情報を記述した設定ファイルのことらしい。~ Device Treeの仕組みはOpen Firmwareを原点にしており、デバイスのベースアドレスや、~ クロック、割り込み番号といった、ハードウェア固有のプロパティをカーネルから分離し~ デバイスドライバの再利用性を高めることが目的としている。~ 結局、ドライバはこの情報を元に、アクセスする。~ Device Treeは2.6.38 以前のLinuxカーネルには存在しない。~ (2.6.38の開発の際に問題となり、対策としてこの手法が以降導入されたらしい)~ ~ Linux コミュニティとしては Device Tree 非対応のデバイスドライバのパッチ受け付けは~ しない決まりになったとのことです。 < ***実装状況 [#c5f78f15] > >サポートされていると「/proc/device-tree/」で情報を取得できるようなので、調べてみます。 # ls /proc/device-tree/ #address-cells __symbols__ chosen cpus memreserve soc #size-cells aliases clocks interrupt-parent model system __overrides__ axi compatible memory name # >サポートはしているようです。新しいカーネルなので、当たり前といえば当たり前ですが。 < **ドライバーサポート [#sd6266a3] > >実際にどのようなドライバーがインストールされているかを調べます。 < ***ドライバーサポート状況 [#zde82794] > >モジュールの一覧を調べます。 # lsmod Module Size Used by brcmfmac 186339 0 brcmutil 5661 1 brcmfmac cfg80211 427855 1 brcmfmac rfkill 16037 1 cfg80211 bcm2835_gpiomem 3040 0 bcm2835_wdt 3225 0 uio_pdrv_genirq 3164 0 uio 8000 1 uio_pdrv_genirq ip_tables 11445 0 x_tables 13165 1 ip_tables ipv6 347466 33 # >この中で、それらしいのを調べて見ます。 < -bcm2835_gpiomem > >たぶんGPIO用のドライバの用です。まずは、調べてみます。~ [[WiringPi>http://wiringpi.com/]]によると ''bcm2835_gpiomem'' により /dev/gpiomem interface が使用できるようになるということで、~ GPIOについてはRasbianと同様のことができることが期待できます。~ 有効ならば、「gpiomem」ができるようです。 # ll /dev/gpiomem crw------- 1 root root 244, 0 1月 1 1970 /dev/gpiomem # < > >ありました。 >次に、rasbianでは、「/sys/class/gpio/」以下に生成されるファイルによりGPI/Oへのアクセスが可能となりますので、あるか調べます。 # ll /sys/class/gpio/ 合計 0 --w------- 1 root root 4096 9月 22 21:30 export lrwxrwxrwx 1 root root 0 9月 22 21:30 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0 lrwxrwxrwx 1 root root 0 9月 22 21:30 gpiochip100 -> ../../devices/platform/soc/soc:virtgpio/gpio/gpiochip100 --w------- 1 root root 4096 9月 22 21:30 unexport # >ありました。~ これらは、以下のudev ruleが設定されていると動作するらしいです。 SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="gpio", MODE="0660" SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'" SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'" < > >その他のドライバはデフォルトでは、サポートしていないようで、別途インストールが必要な予感です。 < ***GPIOへのアクセステスト [#rb26857d] > >では実際にアクセスできるかテストします。 # echo 21 > /sys/class/gpio/export # ls /sys/class/gpio/ export gpio21 gpiochip0 gpiochip100 unexport # ls /sys/class/gpio/gpio21/ active_low device direction edge power subsystem uevent value # echo out > /sys/class/gpio/gpio21/direction # echo 1 > /sys/class/gpio/gpio21/value # echo 0 > /sys/class/gpio/gpio21/value # echo 21 > /sys/class/gpio/unexport # ls /sys/class/gpio/ export gpiochip0 gpiochip100 unexport # < > >まずは、GPIOには簡単にアクセスできる方法は用意されていました。 < **その他のアクセス方法 [#p0bdacb1] ***IIC [#z3035714] > >では、C等でGPIO/IIC/SPIなどのインタフェースはどうすればいいのかを調べました。~ Rasbianでは、ドライバーが用意されているようですが、CentOS7は上記の状況です。~ 検索してみたところ、「BCM 2835」という、CのRaspberry Pi 用のIOライブラリがありました。~ >IIC(I2C)へのアクセスについても、ドライバーレベルでサポートされるようです。 < -ドライバーのイネーブル > >インストールデフォルトでは、ドライバーがイネーブルにならないようで /boot/config.txt にドライバを読み込む設定が必要です。~ 以下の2行を追加します。 dtparam=i2c_arm=on dtparam=i2c1=on < > >これにより、起動時にドライバーを読み込んでくれるようになります。 # lsmod (中略) i2c_dev 6913 0 i2c_bcm2708 5994 0 (以下省略) < > # ll /sys/class/i2c-dev 合計 0 lrwxrwxrwx 1 root root 0 8月 12 09:28 i2c-1 -> ../../devices/platform/soc/3f804000.i2c/i2c-1/i2c-dev/i2c-1 # < **そのほか [#w07ed0d9] > >検索してみたところ、「BCM 2835」という、CのRaspberry Pi 用のIOライブラリがありました。~ 早速ダウンロードしてコードを見ると、IOアドレス空間を直接アクセスしています。~ ぎょっとしましたが、Linux Kernel 2.6.23-rc1からUIOがマージされて、このようなことが可能になったようです。~ コードでは、/dev/memをmmapし、メモリ空間をアクセスしています。また、DeviceTreeにも対応しています。~ 早速、CentOSでも調べてみます。 # ll /dev/mem crw-r----- 1 root kmem 1, 1 1月 1 1970 /dev/mem # >ありました。これでイケルようです。 < **[[BCM 2835>http://www.airspayce.com/mikem/bcm2835/]] [#w338d9a0] **[[LIB BCM 2835>http://www.airspayce.com/mikem/bcm2835/]] [#s967c43e] ***概要 [#y5fbcb8b] > >Raspberry Pi用のCライブラリで、 > This is a C library for Raspberry Pi (RPi). ~ It provides access to GPIO and other IO functions on the Broadcom BCM 2835 chip, ~ allowing access to the GPIO pins on the 26 pin IDE plug on the RPi board ~ so you can control and interface with various external devices.~ It provides functions for reading digital inputs and setting digital outputs, ~ using SPI and I2C, and for accessing the system timers. ~ Pin event detection is supported by polling (interrupts are not supported).~ It is C++ compatible, and installs as a header file and non-shared library ~ on any Linux-based distro (but clearly is no use except on Raspberry Pi ~ or another board with BCM 2835). >とありますので、UART、割り込み以外は、おおよそ何でもできそうです。 < ***ライブラリのビルド [#sa4394e9] > >開発ツールはインストール済みの前提です。 >早速ビルドしてみます。 # cd /opt/ # mkdir bcm2835 # cd bcm2835/ # curl http://www.airspayce.com/mikem/bcm2835/bcm2835-1.50.tar.gz -O # tar zxvf bcm2835-1.50.tar.gz # ls bcm2835-1.50 bcm2835-1.50.tar.gz # cd bcm2835-1.50 # ./configure # make # make install < > >以下のファイルがインストールされます。 < > >> |種別|ファイル|h |Lib|/usr/local/lib/libbcm2835.a| |Header|/usr/local/include/bcm2835.h| |Document|?| << < > >> >>> >>>Kernelをアップデートするたびにmakeしなくてよさそうなのがありがたい。 >>> >>> <<< << >Kernelをアップデートするたびにmakeしなくてよさそうなのがありがたい。 >> << < ***テスト [#r4263da1] > >サンプルのLEDチカチカがありますので、テストします。~ LEDはGPIO-17(コネクタP1の11)に接続し、1秒間隔で点滅(ON:500ms、OFF:500ms)します。 # cd examples/ # cd blink/ # gcc blink.c -o blink_led -l rt -l bcm2835 # ./blink_led < > >※-l rt は[[real-time extensions>http://devlib.symbian.slions.net/belle/GUID-E21287EF-7211-590B-A1E3-E0B37069FCB2.html]]です。(RTカーネルではないので、意味ないかもしれませんが) < お疲れ様でした。