前回はexStickGE上のMicroBlazeで動作するLinuxにEthernetを追加しました.
ネットワークにつながったので今回はHTTPサーバを建ててみたいと思います.
ついでにLEDのLチカを追加します.(ついでと言う割には作業量は結構増えます)
ビルド
HTTPサーバは軽量なlighttpdを使用します.
~/Project以下にserverprjディレクトリを作成し主にその中で作業する予定です.
MicroBlazeのクロスコンパイルはこのディレクトリ以下のソフトウェアを使用します.
/tools/Xilinx/Vitis/2020.1/gnu/microblaze/linux_toolchain/lin64_le/microblazeel-v11.0-bs-cmp-re-mh-div-xilinx-linux
サーバのビルドの下準備
lighttpdをビルドするのに必要な以下のライブラリをビルドしてインストールします.
- zlibc
- pcre
- fastcgi (Lチカするときに使用する)
zlibc
# zlibc cd ~/Project/serverprj wget http://www.zlib.net/zlib-1.2.11.tar.gz tar -xvf zlib-1.2.11.tar.gz cd zlib-1.2.11/ # コンパイラを指定してconfigureを叩く # 追加でインストールディレクトリも指定しておく CC=microblazeel-xilinx-linux-gnu-gcc ./configure --prefix=/tools/Xilinx/Vitis/2020.1/gnu/microblaze/linux_toolchain/lin64_le/microblazeel-v11.0-bs-cmp-re-mh-div-xilinx-linux/usr make sudo make install
pcre
# pcre cd ~/Project/serverprj wget https://ftp.pcre.org/pub/pcre/pcre-8.44.zip unzip pcre-8.44.zip cd pcre-8.44 mkdir build # zlibc同様コンパイラとインストールディレクトリを指定する ./configure --host=microblazeel-xilinx-linux-gnu --prefix=/home/dev/Project/serverprj/pcre-8.44/build make make install
fastcgi
cd ~/Project/serverprj wget https://github.com/FastCGI-Archives/FastCGI.com/raw/master/original_snapshot/fcgi-2.4.1-SNAP-0910052249.tar.gz tar -xvf fcgi-2.4.1-SNAP-0910052249.tar.gz fcgi-2.4.1-SNAP-0910052249/ cd fcgi-2.4.1-SNAP-0910052249/ # config.subで引数のhostに応じたコンパイラ名を # 出してくれるらしいがMicroBlazeは対応していないので誤魔化す cat << EOF > config.sub echo "microblazeel-xilinx-linux-gnu" EOF mkdir dest ./configure --host=microblazeel-xilinx-linux-gnu --prefix=/home/dev/Project/serverprj/fcgi-2.4.1-SNAP-0910052249/dest make make install sudo cp -r dest/* /tools/Xilinx/Vitis/2020.1/gnu/microblaze/linux_toolchain/lin64_le/microblazeel-v11.0-bs-cmp-re-mh-div-xilinx-linux/usr/
lighttpdのビルド
最低限のライブラリをビルドしたのでlighttpdをビルドします.
cd ~/Project/serverprj wget https://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-1.4.59.tar.gz tar -xvf lighttpd-1.4.59.tar.gz cd lighttpd-1.4.59 mkdir dest PCRECONFIG=/home/dev/Project/serverprj/pcre-8.44/build/bin/pcre-config PCRE_LIB=/home/dev/Project/serverprj/pcre-8.44/build/lib/libpcre.a ./configure --host=microblazeel-xilinx-linux-gnu --disable-ipv6 --prefix=/home/dev/Project/serverprj/lighttpd-1.4.59/dest make make install
コンフィグファイルの生成
lighttpdのサンプルコンフィグファイルがdoc/config以下に保存されているので
serverprjディレクトリにコピーして事前に編集しておきます.
cp -r ~/Project/serverprj/lighttpd-1.4.59/doc/config ~/Project/serverprj/
libhttpd.confを編集し93行目をコメントアウト
#server.use-ipv6 = "enable"
modules.confを編集し146行目をアンコメント
include "conf.d/fastcgi.conf"
conf.d/fastcgi.confを編集し8行目以下を編集
server.modules += ( "mod_fastcgi" ) fastcgi.server = ( ".fcgi" => (( "socket" => "/tmp/gpioctl.socket", )) )
Lチカプロジェクトの生成
cd ~/Project/serverprj mkdir lchika cd lchika
lchikaディレクトリ内に”lchika.c”として以下のファイルを作成します.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <fcgi_config.h> #include <fcgi_stdio.h> int list[] = {509, 510, 511}; int init_gpio() { int fd, i; char s[64]; if ((fd = open("/sys/class/gpio/export", O_WRONLY)) < 0) { printf("export open error\n"); return -1; } for (i = 0; i < sizeof(list) / sizeof(list[0]); i++) { sprintf(s, "%d", list[i]); write(fd, s, strlen(s)); } close(fd); for (i = 0; i < sizeof(list) / sizeof(list[0]); i++) { sprintf(s, "/sys/class/gpio/gpio%d/direction", list[i]); if ((fd = open(s, O_WRONLY)) < 0) { printf("direction open error\n"); return -1; } write(fd, "out", 4); close(fd); } return 0; } int finalize_gpio() { int fd, i; char s[64]; if ((fd = open("/sys/class/gpio/unexport", O_WRONLY)) < 0) { printf("export open error\n"); return -1; } for (i = 0; i < sizeof(list) / sizeof(list[0]); i++) { sprintf(s, "%d", list[i]); write(fd, s, strlen(s)); } close(fd); } void set_gpio(int gpio, int val) { int fd, i; char s[64]; sprintf(s, "/sys/class/gpio/gpio%d/value", gpio); if ((fd = open(s, O_WRONLY)) < 0) { printf("value open error\n"); return; } sprintf(s, "%d", val); write(fd, s, strlen(s)); close(fd); } int main() { char *ptr, *str = NULL; int len = 0, frn; int ope_led, ope_val; if (init_gpio() < 0) { return -1; } while (FCGI_Accept() >= 0) { FCGI_printf("Content-type: text/plain\r\n" "\r\n" "Set GPIO LED!\n"); if ((ptr = getenv("QUERY_STRING")) != NULL && (len = strlen(ptr)) > 0) { str = strdup(ptr); } if (str) { ope_led = ope_val = -1; char *head, *eq_p; head = strtok(str, "&"); while (head) { eq_p = strchr(head, '='); if (eq_p) { *eq_p = 0; if (strcmp(head, "led") == 0) { if (sscanf(eq_p + 1, "%d", &ope_led) == 0) { ope_led = -1; FCGI_printf("LED can't convert\n"); }; } else if (strcmp(head, "val") == 0) { if (sscanf(eq_p + 1, "%d", &ope_val) == 0) { ope_val = -1; FCGI_printf("Value can't convert\n"); }; } *eq_p = '='; } head = strtok(NULL, "&"); } FCGI_printf("LED %d VAL %d\n", ope_led, ope_val); FCGI_printf("\n"); free(str); if (0 <= ope_led && ope_led <= 2 && (ope_val == 0 || ope_val == 1)) { set_gpio(list[ope_led], ope_val); } } } finalize_gpio(); return 0; }
コンパイルします.
microblazeel-xilinx-linux-gnu-gcc -o gpioctl.fcgi lchika.c -lfcgi
実際に動かしてみる
ここまでで必要なライブラリ及びソフトウェアが揃ったので実際に動かしていきます.
シリアル通信モジュールを接続し,前回同様にJTAGで動かします.
cd ~/Project/linuxprj/sw petalinux-boot --jtag --fpga petalinux-boot --jtag --kernel
ユーザ名及びパスワードはrootでログインします.
インストール
ここからは地道にビルドしたソフトウェアをコピーしてきます.
#開発用サーバからscpでコピーするためのユーザ情報変数 R_USER=dev R_IP=192.168.0.10 scp -r ${R_USER}@${R_IP}:/home/dev/Project/serverprj/lighttpd-1.4.59/dest/* /usr/ scp -r ${R_USER}@${R_IP}:/home/dev/Project/serverprj/pcre-8.44/build/lib/libpcre.so* /usr/lib scp -r ${R_USER}@${R_IP}:/home/dev/Project/serverprj/fcgi-2.4.1-SNAP-0910052249/dest/* /usr/ mkdir /etc/lighttpd scp -r ${R_USER}@${R_IP}:/home/dev/Project/serverprj/config/* /etc/lighttpd/ mkdir /srv groupadd lighttpd useradd -g lighttpd -d /srv/www -s /sbin/nologin lighttpd mkdir /var/log/lighttpd chown lighttpd:lighttpd /var/log/lighttpd mkdir /srv/www/htdocs scp -r ${R_USER}@${R_IP}:/home/dev/Project/serverprj/lchika/gpioctl.fcgi /srv/www/htdocs cat << EOF > /srv/www/htdocs/index.html <html> <head> <title>Linux on Microblaze</title> </head> <body> <h1>Hello World!</h1> </body> </html> EOF chown -R lighttpd:lighttpd /srv/www/htdocs cgi-fcgi -connect /tmp/gpioctl.socket /srv/www/htdocs/gpioctl.fcgi chmod a+w /tmp/gpioctl.socket lighttpd -f /etc/lighttpd/lighttpd.conf -m /usr/lib
アクセス
ipコマンドでIPアドレスを調べます.今回は192.168.0.215でした.
root@sw:~# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000 link/ether 00:0a:35:00:22:01 brd ff:ff:ff:ff:ff:ff inet 192.168.0.215/24 brd 192.168.0.255 scope global eth0 valid_lft forever preferred_lft forever root@sw:~#
http://192.168.0.215/にアクセスしてみましょう.
次はLEDを操作します.
http://192.168.0.215/gpioctl.fcgiがアドレスでパラメータを用いて制御します.
ledが0~2で上の図の509~511に対応します.
valは0か1で0=消灯,1=点灯に対応します.
例えば以下のURLであればシルクでLED4の緑色が点灯します.
http://192.168.0.215/gpioctl.fcgi?led=1&val=1
全部点灯させてみました.
http://192.168.0.215/gpioctl.fcgi?led=0&val=1
http://192.168.0.215/gpioctl.fcgi?led=2&val=1
まとめ
Ubuntu上でMicroblaze用のソフトウェアをコンパイルし実機上で動作を確認できました.
現状はシンプルに起動したあとソフトウェアを追加する形をとっています.
実際に運用する場合にはすべてまとめた状態にするべきですが,
リセットすれば初期化されるのでこれはこれで便利だと思っています.
HTTPによる制御が可能になったのでブラウザ経由で
FPGAがかんたんに操作できます.
是非試してみてください.
コメント
[…] Sierra Wireless社のLegatoフレームワークにもlighttpdを使用したサンプルアプリケーションが存在します.しかし今回はWP7605を通常のLinuxマシンのように使用する前提で別途lighttpdをビルドしサーバとして運用することにします.以前MicroBlazeで使用したのを参考にビルドしていきます. […]