DragonBoard 410c(Debian)でGPIOプログラミング(C言語編):少し解決

DragonBoard 410c(Debian)でGPIOプログラミング(C言語編):少し解決

前回のエントリではなかなかタクトスイッチを使ったGPIOの入力処理がうまく行かず途中で中断してしまいました。

タクトスイッチの回路をArduinoで動作するか試したり、プログラムを直したりとしていましたが、状況は好転しませんでした。

uepon.hatenadiary.com

ふと思い、GPIO_Bが原因?ではないかと思いGPIO_Cに変更してみました。 あと、タクトスイッチを押したらLEDが点灯する様にソースも編集しました。

【blink.c】

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <gpio.h>

#define LED "GPIO-A"
#define TOUCH "GPIO-C"

int main()
{
        int x;
        int t = 0;
        int last_t = 0;
        int led_state = HIGH;

        if(gpio_open(gpio_id(LED), "out")){
                return (-1);
        }
        if (gpio_open(gpio_id(TOUCH), "in")){
                return(-1);
        }

        while(1){
                t = digitalRead(gpio_id(TOUCH));
                if (t && !last_t){
                        digitalWrite(gpio_id(LED), led_state);
                        usleep(100000);
                        if(led_state == HIGH){
                                led_state = LOW;
                                printf("HIGH\n");
                        } else {
                                led_state = HIGH;
                                printf("LOW\n");
                        }
                }
                last_t = t;
                usleep(1);
        }

        digitalWrite(gpio_id(LED), LOW);
        return EXIT_SUCCESS;
}

入力処理

入力に使用するGPIOのピンをTOUCHとしておき、方向を"in"とすればオープンは完了です。

if (gpio_open(gpio_id(TOUCH), "in")){
                return(-1);
        }

入力値の取得はdigitalRead()となります。引数にピン番号を与えることでOKです。値はintで帰ってきますが、HIGHtおLOWでも判別ができるようになっています。

                t = digitalRead(gpio_id(TOUCH));

ではあらためて、makeして実行してみると…

$ make
gcc -DPACKAGE_NAME=\"96BoardsGPIO\" -DPACKAGE_TARNAME=\"96boardsgpio\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"96BoardsGPIO\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"96boardsgpio\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -I.    -l96BoardsGPIO -g -O2 -MT blink-blink.o -MD -MP -MF .deps/blink-blink.Tpo -c -o blink-blink.o `test -f 'blink.c' || echo './'`blink.c
mv -f .deps/blink-blink.Tpo .deps/blink-blink.Po
/bin/bash ../libtool  --tag=CC   --mode=link gcc -l96BoardsGPIO -g -O2   -o blink blink-blink.o  -lsoc
libtool: link: gcc -g -O2 -o blink blink-blink.o  -l96BoardsGPIO -lsoc
$ sudo ./blink
HIGH
LOW
HIGH
LOW
HIGH
LOW
^C

あれ?すんなり動きました。

動作中の動画は後日追記します。

動作状況の動画になります。

youtu.be

おわりに

GPIO_Bが動かないのは原因がわかりませんが、一応動いたので今回のエントリーとしては解決とします。GPIOのピンごとの設定ってあるんでしょうかね。

DragonBoard 410c(Debian)でGPIOプログラミング(C言語編):課題あり

DragonBoard 410c(Debian)でGPIOプログラミング(C言語編)

以前のエントリーでは、設定まで行うまででした。そこで今回は動作確認を行ったサンプルのソースを確認していこうと思います。

先日ソースからインストールを行った96BoardsGPIOのexampleディレクトリにサンプルはあります。

ドキュメント関係もこちらがいいかなと思います。

github.com

念のためピンアサインも

https://az835927.vo.msecnd.net/sites/iot/Resources/images/PinMappings/DB_Pinout.png

C言語

exampleディレクトリにあるblink.cファイルを開きます。

このプログラムの処理としては以下のような手順になっています。

  1. GPIOのポート指定(といってもポート番号の設定だけ)
  2. 指定したGPIOポートのオープン(open()のような使い方をする模様)
  3. 指定したGPIOポートへのRead/Write(exampleではLチカなのでwriteのみ)

こんな感じになります。なんとなくの印象ですがシステムコールopen()の引数にPathがないような使い方で良いようです。

ではソースを眺めてみます。

【example/blink.c】

#include <stdio.h>

/* 96BoardsGPIO header file */
#include <gpio.h>

/* Just make the pin numbers easier to remember */

int main(int argc, char * argv[])
{
        int x;
        unsigned int gpio_a = gpio_id("GPIO_A");
        /*
         * GPIO_A can also be looked up with:
         *  gpio_a = gpio_by_letter('A');
         *  gpio_a = gpio_by_pin(23);
         */

        // Open the GPIO for use.  Do so by pin number on the
        // Low Speed Expansion Connector.
        if (!gpio_open(gpio_a, "out")) {
                for (x=0; x<10; x++) {
                        digitalWrite(gpio_a, HIGH);
                        usleep(500000);
                        digitalWrite(gpio_a, LOW);
                        usleep(500000);
                }
        } else {
                fprintf(stderr, "Unable to open GPIO_A\n");
                return -1;
        }

        return 0;
}

include部分

いちばん重要なincludeの部分はgpio用のヘッダファイルをincludeファイルします。 この中ではlibsocのヘッダファイルもincludeされていますのでこれだけでいいようです。

/* 96BoardsGPIO header file */
#include <gpio.h>

GPIOのポート指定

あとは、ほぼ上記の手順そのままですが、GPIOのポート指定では3タイプの指定が可能のようです。

        unsigned int gpio_a = gpio_id("GPIO_A");
        /*
         * GPIO_A can also be looked up with:
         *  gpio_a = gpio_by_letter('A');
         *  gpio_a = gpio_by_pin(23);
         */

GPIO_Aのような指定、ポートに割り当てられている文字の指定、ダイレクトにGPIOのpinナンバーの指定、この3つのうちのどれかを指定することになります。 自分が開発を行うのであれば、ピン番号を直接指定するほうが楽かなと思いますけど、96Boards仕様のボードでのソースの移植を行うのであればサンプルと同じ方がいいのかなと思います。動作は同じようです。

指定したGPIOポートのオープン

if (!gpio_open(gpio_a, "out")) {

使用するGPIOのポートとin/outの方向を指定してgpio_open()を呼び出します。

出力処理

                        digitalWrite(gpio_a, HIGH);
                        //略
                        digitalWrite(gpio_a, LOW);
                        //略

あとは、GPIOのピンに対してHIGH/LOWを指定すれば出力が行われます。

make

そのファイルをmakeしてみると以下のようなWarningが発生しますが、成功します。

$ make
gcc -DPACKAGE_NAME=\"96BoardsGPIO\" -DPACKAGE_TARNAME=\"96boardsgpio\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"96BoardsGPIO\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"96boardsgpio\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -I.    -l96BoardsGPIO -g -O2 -MT blink-blink.o -MD -MP -MF .deps/blink-blink.Tpo -c -o blink-blink.o `test -f 'blink.c' || echo './'`blink.c
blink.c: In function ‘main’:
blink.c:24:4: warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]
    usleep(500000);
    ^~~~~~
mv -f .deps/blink-blink.Tpo .deps/blink-blink.Po
/bin/bash ../libtool  --tag=CC   --mode=link gcc -l96BoardsGPIO -g -O2   -o blink blink-blink.o  -lsoc
libtool: link: gcc -g -O2 -o blink blink-blink.o  -l96BoardsGPIO -lsoc

usleep()が明示的に宣言されてないよっていう感じなので宣言をすればWarningはなくなると思います。具体的にはinclude部分で#include <unistd.h>を追加すればOKです。

【修正前】

#include <stdio.h>

/* 96BoardsGPIO header file */
#include <gpio.h>

【修正後】

#include <stdio.h>
#include <unistd.h>

/* 96BoardsGPIO header file */
#include <gpio.h>

変更すると

$ make
gcc -DPACKAGE_NAME=\"96BoardsGPIO\" -DPACKAGE_TARNAME=\"96boardsgpio\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"96BoardsGPIO\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"96boardsgpio\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -I.    -l96BoardsGPIO -g -O2 -MT blink-blink.o -MD -MP -MF .deps/blink-blink.Tpo -c -o blink-blink.o `test -f 'blink.c' || echo './'`blink.c
mv -f .deps/blink-blink.Tpo .deps/blink-blink.Po
/bin/bash ../libtool  --tag=CC   --mode=link gcc -l96BoardsGPIO -g -O2   -o blink blink-blink.o  -lsoc
libtool: link: gcc -g -O2 -o blink blink-blink.o  -l96BoardsGPIO -lsoc

Warningはなくなりました。

入力

digitalWrite()でLチカができたので今度は入力もやってみたいなあと思いました。

#include <stdio.h>
#include <unistd.h>

#include <gpio.h>

int main(int argc, char * argv[])
{
        int x;
        int v;
        unsigned int gpio_b = gpio_id("GPIO_B");

        if (!gpio_open(gpio_b, "in")) {
                for (x=0; x<3; x++) {
            v = digitalRead(gpio_b);
                        if (v != -1){
                                if (v == HIGH){
                                        printf("HIGH\n");
                                }
                                else {
                                        printf("LOW\n");
                                }
                        }
                        usleep(500000);
                }
        } else {
                fprintf(stderr, "Unable to open GPIO_B\n");
                return -1;
        }

        return 0;
}

このようなファイルにしてタクトスイッチの状態を調べたのですが、どうしてもうまくいきません。値が固定になっているような気がします。スイッチを押しても離してもHIGHのままで、スイッチ回路を諦めてGNDに直結してもNGでした。

$ make ; sudo ./blink
HIGH
HIGH
HIGH

GPIO_Bを使用していたのでもしかしてGPIOのピン側に問題があるのかなと思い、output側でテストすると問題なくLチカはできました。

その後、同じプログラムを実行すると

$ sudo ./blink
LOW
LOW
LOW

今度は固定的にLOWのままになってしまいました。起動時はHIGHで、変更があった際にはそのあとの値が保持されている様です。

ちょっと自分にはお手上げ感ありです。 inputのサンプル実験している人も見当たらず。うーん。

おわりに

Lチカが終わったので結構安心していたのですが、入力に関してはまだうまく行っていません。もう少し調べたいと思います。

【自分だけではなかった…】DragonBoard 410c(Debian)の定期的なリブート対策

DragonBoard 410c(Debian)の定期的なリブート対策

どうもDragonBoardでリブートが頻発するのは自分だけの現象ではなかったようです。 Facebookでも同じ現象の方が多くなってきているようです(?)

このエントリーは過去のエントリーからの継続ネタになります。概ねの解決編となります。

uepon.hatenadiary.com

uepon.hatenadiary.com

しかし、Bluetoothをオフにして、HDMIも接続しなければほとんどリブートしないみたいですね。syslogの内容でvblank time outという部分みると、もしかしたらHDMIの方が原因なのかも…?

前回のエントリーではこういう感じで締めくくってみたのですが、実際に実験をしてみました。

Bluetoothを有効化する

Bluetoothを無効化していたので、まずは有効化させます。

$ sudo systemctl enable bluetooth.service
$ sudo systemctl start bluetooth.service

HDMIを外す

そして、本体からMHDMIケーブルを外して再起動します。

$ tail -f /var/log/messages

一応、syslogを確認しながら長時間動作を確認します。 開始から一日以上経ちましたが、安定して動作しているようです。

原因は…

本当の原因はHDMI側の処理だったのかなと思います。

自分の場合、実際にはヘッドレスな運用をすることがほとんどなので、これであれば問題ないかなと思いました。とはいうもののXを使いたいということはたまにあります。例えば、OpenCVなどで画像を表示したいという場合などです。

そこでWindowsリモートデスクトップ接続からも使えるようにします。

リモートデスクトップ接続の設定を行う。

過去に行ったRaspberryPiでの設定をベースに行います。

uepon.hatenadiary.com

念のため、x11vncのパッケージがあるか確認します。

$ sudo apt-chache search x11vnc
ssvnc - Enhanced TightVNC viewer with SSL/SSH tunnel helper
x11vnc - VNC server to allow remote access to an existing X session
x11vnc-data - data files for x11vnc

無事存在していました。ではインストール作業を行います。

$ sudo apt-get install xrdp
$ sudo apt-get install x11vnc

これでOKです。

x11vncの設定

VNC接続用のパスワードファイルを作成します。

$ x11vnc -storepasswd
Enter VNC password: 
Verify password:    
Write password to /home/linaro/.vnc/passwd?  [y]/n 
Password written to: /home/linaro/.vnc/passwd

これで準備は完了です。コマンドラインからx11vncを起動します。-usepwは先程作成したパスワードファイルを使用するという意味になります。

$ x11vnc -usepw
03/06/2017 09:46:46 -usepw: found /home/linaro/.vnc/passwd
03/06/2017 09:46:46 x11vnc version: 0.9.13 lastmod: 2011-08-10  pid: 2998
03/06/2017 09:46:46 XOpenDisplay("") failed.
03/06/2017 09:46:46 Trying again with XAUTHLOCALHOSTNAME=localhost ...
03/06/2017 09:46:46 
03/06/2017 09:46:46 *** XOpenDisplay failed. No -display or DISPLAY.
03/06/2017 09:46:46 *** Trying ":0" in 4 seconds.  Press Ctrl-C to abort.
03/06/2017 09:46:46 *** 1 2 3 4 
03/06/2017 09:46:50 *** XOpenDisplay of ":0" successful.
03/06/2017 09:46:50 
03/06/2017 09:46:50 Using X display :0
03/06/2017 09:46:50 rootwin: 0x205 reswin: 0x2200001 dpy: 0xe4366350
03/06/2017 09:46:50 
03/06/2017 09:46:50 ------------------ USEFUL INFORMATION ------------------
03/06/2017 09:46:50 X DAMAGE available on display, using it for polling hints.
03/06/2017 09:46:50   To disable this behavior use: '-noxdamage'
03/06/2017 09:46:50 
03/06/2017 09:46:50   Most compositing window managers like 'compiz' or 'beryl'
03/06/2017 09:46:50   cause X DAMAGE to fail, and so you may not see any screen
03/06/2017 09:46:50   updates via VNC.  Either disable 'compiz' (recommended) or
03/06/2017 09:46:50   supply the x11vnc '-noxdamage' command line option.
03/06/2017 09:46:50 
03/06/2017 09:46:50 Wireframing: -wireframe mode is in effect for window moves.
03/06/2017 09:46:50   If this yields undesired behavior (poor response, painting
03/06/2017 09:46:50   errors, etc) it may be disabled:
03/06/2017 09:46:50    - use '-nowf' to disable wireframing completely.
03/06/2017 09:46:50    - use '-nowcr' to disable the Copy Rectangle after the
03/06/2017 09:46:50      moved window is released in the new position.
03/06/2017 09:46:50   Also see the -help entry for tuning parameters.
03/06/2017 09:46:50   You can press 3 Alt_L's (Left "Alt" key) in a row to 
03/06/2017 09:46:50   repaint the screen, also see the -fixscreen option for
03/06/2017 09:46:50   periodic repaints.
03/06/2017 09:46:50 
03/06/2017 09:46:50 XFIXES available on display, resetting cursor mode
03/06/2017 09:46:50   to: '-cursor most'.
03/06/2017 09:46:50   to disable this behavior use: '-cursor arrow'
03/06/2017 09:46:50   or '-noxfixes'.
03/06/2017 09:46:50 using XFIXES for cursor drawing.
03/06/2017 09:46:50 GrabServer control via XTEST.
03/06/2017 09:46:50 
03/06/2017 09:46:50 Scroll Detection: -scrollcopyrect mode is in effect to
03/06/2017 09:46:50   use RECORD extension to try to detect scrolling windows
03/06/2017 09:46:50   (induced by either user keystroke or mouse input).
03/06/2017 09:46:50   If this yields undesired behavior (poor response, painting
03/06/2017 09:46:50   errors, etc) it may be disabled via: '-noscr'
03/06/2017 09:46:50   Also see the -help entry for tuning parameters.
03/06/2017 09:46:50   You can press 3 Alt_L's (Left "Alt" key) in a row to 
03/06/2017 09:46:50   repaint the screen, also see the -fixscreen option for
03/06/2017 09:46:50   periodic repaints.
03/06/2017 09:46:50 
03/06/2017 09:46:50 XKEYBOARD: number of keysyms per keycode 10 is greater
03/06/2017 09:46:50   than 4 and 100 keysyms are mapped above 4.
03/06/2017 09:46:50   Automatically switching to -xkb mode.
03/06/2017 09:46:50   If this makes the key mapping worse you can
03/06/2017 09:46:50   disable it with the "-noxkb" option.
03/06/2017 09:46:50   Also, remember "-remap DEAD" for accenting characters.
03/06/2017 09:46:50 
03/06/2017 09:46:50 X FBPM extension not supported.
03/06/2017 09:46:50 X display is capable of DPMS.
03/06/2017 09:46:50 --------------------------------------------------------
03/06/2017 09:46:50 
03/06/2017 09:46:50 Default visual ID: 0x21
03/06/2017 09:46:50 Read initial data from X display into framebuffer.
03/06/2017 09:46:50 initialize_screen: fb_depth/fb_bpp/fb_Bpl 24/32/4096
03/06/2017 09:46:50 
03/06/2017 09:46:50 X display :0 is 32bpp depth=24 true color
03/06/2017 09:46:50 
03/06/2017 09:46:50 Autoprobing TCP port 
03/06/2017 09:46:50 Autoprobing selected TCP port 5900
03/06/2017 09:46:50 Autoprobing TCP6 port 
03/06/2017 09:46:50 Autoprobing selected TCP6 port 5900
03/06/2017 09:46:50 listen6: bind: Address already in use
03/06/2017 09:46:50 Not listening on IPv6 interface.
03/06/2017 09:46:50 fb read rate: 91 MB/sec
03/06/2017 09:46:50 fast read: reset -wait  ms to: 10
03/06/2017 09:46:50 fast read: reset -defer ms to: 10
03/06/2017 09:46:50 The X server says there are 16 mouse buttons.
03/06/2017 09:46:50 screen setup finished.
03/06/2017 09:46:50 

The VNC desktop is:      linaro-alip:0
PORT=5900

******************************************************************************
Have you tried the x11vnc '-ncache' VNC client-side pixel caching feature yet?

The scheme stores pixel data offscreen on the VNC viewer side for faster
retrieval.  It should work with any VNC viewer.  Try it by running:

    x11vnc -ncache 10 ...

One can also add -ncache_cr for smooth 'copyrect' window motion.
More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching

これで接続準備ができましたので接続テストを行います。

リモートデスクトップ接続ツールを起動して

f:id:ueponx:20170603145950p:plain

無事に接続ができるとxrdpの接続画面が表示されます。

f:id:ueponx:20170603150146p:plain

Session : vnc-any IP : DragonboadのIPアドレス port : 5900 password : 先程設定したパスワード

と入力して【OK】ボタンをクリックします。

f:id:ueponx:20170603150836p:plain

無事に接続できました。(画面は接続後ターミナルを立ち上げてみています) あとは、自動で起動するように設定を行っていきます。 とりあえず、Ctrl+cでx11vncを終了します。

設定ファイルを生成します。

$ mkdir /home/linaro/.config/autostart/
$ vim /home/linaro/.config/autostart/x11vnc.desktop

【x11vnc.desktop】

[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=X11VNC
Comment=
Exec=x11vnc -forever -display :0 -rfbauth /home/linaro/.vnc/passwd
StartupNotify=false
Terminal=false
Hidden=false

これでOKです。後は自動ログインの設定を行えば問題ないのですが、RaspberryPiの様にraspi-configで設定ができないのですが…何もしなくても再起動するとx11vncが起動していました。ターミナルからのログインはしていません。

なんとかこれでXが使用できるようになりました。

おわりに

無事にXも使えるし、Bluetoothも使えるようになりました。これでおおよその問題も解決できたかなと思います。

ただ、リモートで使うXがRaspberryPiよりもかなり遅く感じます。

DragonBoard 410c(Debian)の再起動の原因を調べる

DragonBoard 410c(Debian)の再起動の原因を調べる

以前、DragonBoard 410cの再起動が定期的に発生する事象があって、Bluetoothの機能を停止したら治った(収まった)というエントリーを書きました。

uepon.hatenadiary.com

その後コミュニティで以下のようなログが出ると死ぬよって話がありました。自分はsyslogのとり方などは詳しくないのであらためて調べることにしました。

[ 5088.293666] msm 1a00000.mdss: vblank time out, crtc=0
[ 5088.357655] msm 1a00000.mdss: vblank time out, crtc=0

ちなみに自分がDragonBoard死んだかどうかを確認するときにつかっていたのはbashのループとか、watchコマンドでした。以下は10秒おきにコマンドをdate実行する例です。

bashでループさせる場合】

$ while true; do date; sleep 10s; done

【watchを使う場合】

$ watch -n 10 date

ググって以下のコマンドがいいかなと思いました。

$ tail -f /var/log/messages

あとはTeratermのログ記録モードにしておけば再起動したおおよその時刻がわかります。自分のDragonBoardも以下のようなログとともに再起度していたので原因は同じ様です。

Jun  1 22:41:23 linaro-alip kernel: [  383.872879] random: crng init done
Jun  1 22:46:41 linaro-alip kernel: [  701.710271] msm 1a00000.mdss: vblank time out, crtc=0
Jun  1 22:46:41 linaro-alip kernel: [  701.766224] msm 1a00000.mdss: vblank time out, crtc=0

終わりに

しかし、Bluetoothをオフにして、HDMIも接続しなければほとんどリブートしないみたいですね。

syslogの内容でvblank time outという部分みると、もしかしたらHDMIの方が原因なのかも…?

DragonBoard 410c(Debian)でGPIOを使用する

DragonBoard 410c(Debian)でGPIOを使用する

そろそろDragonBoard(debian)でもGPIOを使用したくなってきましたので、GPIOを使用するための設定を行いたいと思います。

お急ぎの方は下の方にある解答編まで飛ばしてください。

手順

DragonBoard(debian)でGPIOを使用するには2つののライブラリが必要になります。

  • libsoc
  • 96BoardsGPIO

これらを用いることでGPIOがC言語およびpythonでも使用できるようになります。 ※pythonに関しては言語用Bindingがあるので、それを経由してLibraryにアクセスすることになります。

今回はこちらを参考にさせていただいています。

qiita.com

参考にしていたエントリのまんまなので楽勝と思っている自分がいました。

f:id:ueponx:20170528160909j:plain

基本的にはどちらもソースファイルをGithubから取得しbuildしていくというものになります。

buildに必要なパッケージのインストー

96BoardsGPIOをbuildする際にautogen.shを使用するので以下のパッケージを事前にインストールしておきます。

$ sudo apt-get install autoconf automake libtool

事前の準備は終了しました。

libsocをインストールする

libsocのgithubページは以下になります。

github.com

$ git clone https://github.com/jackmitch/libsoc.git
$ cd libsoc
$ autoreconf -i
$ ./configure --enable-board="dragonboard410c"
$ make
$ sudo make install

以上の手順で無事にインストールできました。

96BoardsGPIOをインストールする

github.com

手順を確認すると以下の様になるのですが…

$ git clone https://github.com/96boards/96BoardsGPIO.git
$ cd 96BoardsGPIO
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig

makeを実行すると以下のようにErrorが発生してしまいます。

$ make
Making all in lib
make[1]: Entering directory '/home/linaro/96BoardsGPIO/lib'
/bin/bash ../libtool  --tag=CC   --mode=compile gcc -DPACKAGE_NAME=\"96BoardsGPIO\" -DPACKAGE_TARNAME=\"96boardsgpio\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"96BoardsGPIO\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"96boardsgpio\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -I.  -I../lib   -g -O2 -MT lib96BoardsGPIO_la-gpio.lo -MD -MP -MF .deps/lib96BoardsGPIO_la-gpio.Tpo -c -o lib96BoardsGPIO_la-gpio.lo `test -f 'gpio.c' || echo './'`gpio.c
libtool: compile:  gcc -DPACKAGE_NAME=\"96BoardsGPIO\" -DPACKAGE_TARNAME=\"96boardsgpio\" -DPACKAGE_VERSION=\"0.1\" "-DPACKAGE_STRING=\"96BoardsGPIO 0.1\"" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"96boardsgpio\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -I. -I../lib -g -O2 -MT lib96BoardsGPIO_la-gpio.lo -MD -MP -MF .deps/lib96BoardsGPIO_la-gpio.Tpo -c gpio.c  -fPIC -DPIC -o .libs/lib96BoardsGPIO_la-gpio.o
gpio.c: In function ‘gpio_id’:
gpio.c:63:17: warning: implicit declaration of function ‘strdup’ [-Wimplicit-function-declaration]
   char *fixed = strdup(pin_name);
                 ^~~~~~
gpio.c:63:17: warning: incompatible implicit declaration of built-in function   strdup’
gpio.c: In function ‘gpio_open’:
gpio.c:98:41: error: ‘LS_SHARED’ undeclared (first use in this function)
  gpio *g = libsoc_gpio_request(gpio_id, LS_SHARED);
                                         ^~~~~~~~~
gpio.c:98:41: note: each undeclared identifier is reported only once for each function it appears in
gpio.c:101:7: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]
  if (!strcmp(direction, "in"))
       ^~~~~~
Makefile:459: recipe for target 'lib96BoardsGPIO_la-gpio.lo' failed
make[1]: *** [lib96BoardsGPIO_la-gpio.lo] Error 1
make[1]: Leaving directory '/home/linaro/96BoardsGPIO/lib'
Makefile:459: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1

warningは目を瞑るとして、

gpio.c:98:41: error: ‘LS_SHARED’ undeclared (first use in this function)
  gpio *g = libsoc_gpio_request(gpio_id, LS_SHARED);
                                         ^~~~~~~~~
gpio.c:98:41: note: each undeclared identifier is reported only once for each function it appears in

エラーメッセージから推測するとLS_SHAREDというシンボルが読み取れないということのようです。LS_SHAREDはlibsocのヘッダーファイルに定義されていたので、ヘッダーファイルのパスが想定とは違っているようです。っていうか、参考にしたサイトはこれでいいということのようなんですが、OSのバージョンということなんでしょうか。

色々試してみたのですが、自分のキャパを超えていたのでどうすればいいかわからず、OSを入れたりconfigureをいじってみたり、オプションを変えてみたりしました。

解答編

OSを何度もいれたりして試したのですが諦めて色々と調べているとlibsocのLibraryのReadmeに以下のような部分を発見。

First, check if your distro packages libsoc. If it does it is easiest to install your distros version of libsoc through it’s provided package manager. Depending on your distro this may be apt-get, yum, pacman, etc. Consult your distro documentation for more info

もしかしてパッケージ化されたLibraryがあるんじゃない?と思って試してみました。

あるし… (ちなみになぜかデフォルトでlibsocのpythonバインドのパッケージが既にインストールされています。)

気を取り直して、まっさらな状態からのインストール手順をまとめます。

$ sudo apt-get install autoconf automake libtool
$ sudo apt-get install libsoc2 libsoc-dev python-libsoc
$ git clone https://github.com/96boards/96BoardsGPIO.git
$ cd 96BoardsGPIO/
$ ./autogen.sh
$ ./configure
$ make

...()...

gpio.Tpo -c gpio.c  -fPIC -DPIC -o .libs/lib96BoardsGPIO_la-gpio.o
gpio.c: In function ‘gpio_id’:
gpio.c:63:17: warning: implicit declaration of function ‘strdup’ [-Wimplicit-function-declaration]
   char *fixed = strdup(pin_name);
                 ^~~~~~
gpio.c:63:17: warning: incompatible implicit declaration of built-in function   strdup’
gpio.c: In function ‘gpio_open’:
gpio.c:101:7: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]
  if (!strcmp(direction, "in"))
       ^~~~~~
...()...

$ sudo make install
$ sudo ldconfig

今回はwaringは発生していますが、Errorは発生せずにインストールできるようになりました。(96BoardsGPIOのインストール手順は変更ありません。)

これでOKです。

サンプルの実行

インストールが無事終了したので実際のサンプルでLチカを行ってみたいと思います。

https://az835927.vo.msecnd.net/sites/iot/Resources/images/PinMappings/DB_Pinout.png

上記の図を参考に

  • PIN1がGND
  • PIN23がGPIO-A

としてLEDを接続します。 96BoardsGPIOのソースにあるexampleディレクトリに移動して、サンプルソースmakeを行い成功したらできた実行ファイルを実行します。

$ cd examples/
$ make
$ sudo ./blink

するとこのようになります。

【動画】

youtu.be

無事にLチカすることができました。 同じフォルダにあるpythonのサンプルでもLチカはできています。

設定は終わったはずなんだけど…

インストール後に再度ログインするとログイン時にErrorが発生しています。

Linux linaro-alip 4.9.27-linaro-lt-qcom #1 SMP PREEMPT Wed May 10 19:59:33 UTC 2017 aarch64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed May 24 19:26:42 2017 from 192.168.0.7
ERROR: Unable to find libsoc_gpio.conf
cat: /usr/local/etc/libsoc_gpio.conf: No such file or directory
declare -x HOME="/home/linaro"
declare -x JAVA_TOOL_OPTIONS="-Dgnu.io.rxtx.SerialPorts=/dev/tty96B0"
declare -x LANG="C.UTF-8"
declare -x LOGNAME="linaro"
declare -x MAIL="/var/mail/linaro"
declare -x MONITOR_PORT="/dev/tty96B0"
declare -x OLDPWD
declare -x PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
declare -x PWD="/home/linaro"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_CLIENT="192.168.0.7 7154 22"
declare -x SSH_CONNECTION="192.168.0.7 7154 192.168.0.8 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="xterm"
declare -x USER="linaro"
declare -x XDG_RUNTIME_DIR="/run/user/1000"
declare -x XDG_SESSION_ID="5"
linaro@linaro-alip:~$

エラーメッセージを確認するとERROR: Unable to find libsoc_gpio.confというエラーが発生しています。libsocの設定ファイルがみあたらないようです。ソースからインストールした時には発生しなようですが、パッケージでのインストールでは発生してしまっているようです。

仕方なくエラーメッセージからググってみると…

discuss.96boards.org

というようなページを見つけました。なければ作れということのようです。 そこで以下のファイルを開いて

$ sudo vi /etc/libsoc_gpio.conf

以下のように編集します。

【/etc/libsoc_gpio.conf】

# board
model = Qualcomm Technologies, Inc. APQ 8016 SBC

# GPIO
# dragonboard 410c pin layout
#<Pin Name> = <SoC Num>
GPIO_A = 36
GPIO_B = 12
GPIO_C = 13
GPIO_D = 69
GPIO_E = 115
GPIO_F = 4
GPIO_G = 24
GPIO_H = 25
GPIO_I = 35
GPIO_J = 34
GPIO_K = 28
GPIO_L = 33

# include mappings by pin number on board
GPIO_23 = 36
GPIO_24 = 12
GPIO_25 = 13
GPIO_26 = 69
GPIO_27 = 115
GPIO_28 = 4
GPIO_29 = 24
GPIO_30 = 25
GPIO_31 = 35
GPIO_32 = 34
GPIO_33 = 28
GPIO_34 = 33

内容としてはGPIOのpinとアサインの設定を記載したファイルになるのだと思います。 このあと再度ログインをするとエラメッセージは消えました。

終わりに

今回もいろいろと迷い路をしていましたが、ようやくDragonBoardでもGPIOが使用できるようになりました。電圧が1.8Vなのが気になりますが、これからまた考えていこうかと思います。

/* -----codeの行番号----- */