*[[CentOSからI/Oをアクセス]] [#m5789035] **はじめに [#e7e50907] > >Raspberry Pi 3にCentOS7をインストールした場合のI/Oへのアクセス方法をまとめました。~ Rasbianでは、各種の方法が提供されているようですが、CentOSの対応状況が不明です。~ そのため、調べた結果をメモします。 < **デバイスツリーサポート状況 [#u0dd2208] ***デバイスツリー(Device Tree)とは [#l63c5a03] > >聞き慣れない用語ですが、I/Oアクセスに関する記事を検索すると、よく見かけます。~ 結局のところ、ARM Linux 用のプロパティ情報を記述した設定ファイルのことらしい。~ Device Treeの仕組みはOpen Firmwareを原点にしており、デバイスのベースアドレスや、~ クロック、割り込み番号といった、ハードウェア固有のプロパティをカーネルから分離し~ デバイスドライバの再利用性を高めることが目的としている。~ 結局、ドライバはこの情報を元に、アクセスする。~ Device Treeは2.6.38 以前のLinuxカーネルには存在しない。~ (2.6.38の開発の際に問題となり、対策としてこの手法が以降導入されたらしい)~ ~ Linux コミュニティとしては Device Tree 非対応のデバイスドライバのパッチ受け付けは~ しない決まりになったとのことです。 < ***実装状況 [#cd5f269c] > >サポートされていると「/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 # >サポートはしているようです。新しいカーネルなので、当たり前といえば当たり前ですが。 < **ドライバーサポート [#o481c438] > >実際にどのようなドライバーがインストールされているかを調べます。 < ***ドライバーサポート状況 [#j396b47f] > >モジュールの一覧を調べます。 # 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へのアクセステスト [#q64a032a] > >では実際にアクセスできるかテストします。 # 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には簡単にアクセスできる方法は用意されていました。 < **その他のアクセス方法 [#ef3f172c] > >では、C等でGPIO/IIC/SPIなどのインタフェースはどうすればいいのかを調べました。~ Rasbianでは、ドライバーが用意されているようですが、CentOS7は上記の状況です。~ 検索してみたところ、「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/]] [#e778179f] ***概要 [#d8175bcb] > >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、割り込み以外は、おおよそ何でもできそうです。 < ***ライブラリのビルド [#df5725b4] > >早速ビルドしてみます。 # 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しなくてよさそうなのがありがたい。 < ***テスト [#re19c440] > >サンプルの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カーネルではないので、意味ないかもしれませんが) < お疲れ様でした。