ZYBO Z7によるZYNQ入門 (7)Linux環境でUDP通信(ユーザアプリ)
- (1)Vivado, Xilink SDK開発環境構築
 - (2)Hello Worldプログラムによる動作確認
 - (3)Ubuntu, PetaLinuxツール環境構築
 - (4)ベアメタル環境のlwIPでUDP通信
 - (5)PetaLinuxツールでLinuxイメージを作成
 - (6)Linux環境でUDP通信(iperf)
 - (7)Linux環境でUDP通信(ユーザアプリ)
 - (8)Audio Codec
 - (9)AXI DMAを使用したPL-PS間のデータ転送
 
環境
- PC: Windows 10 64bit
- Xilink SDK 2019.1
 - Tera Term
 
 - PC (Linux): Ubuntu 18.04
- Petalinuxツール 2019.1
 
 - ボード: ZYBO (Z7-10)
- micro USBケーブル
 - Ethernetケーブル
 - microSDカード (Class10, 4-32GB)
 
 
LinuxのユーザアプリでUDP通信
次はZYBO上のLinuxにユーザアプリを実装して、UDP通信を行います。
- Ubuntu PC (Server) : 192.168.1.12
 - ZYBO (Client) : 192.168.1.10
 
Xilinx SDKでLinuxユーザアプリ作成
プロジェクト作成
PetaLinuxツールでもユーザアプリの開発ができますが、ビルドしてSDカードに書き込んでのデバッグとなるため、Xilink SDKでユーザアプリの開発を行います。
SDK上のメニューバー -> New -> Application Project で、新しいソフトウェアプロジェクトを作成します。
- Project name: udpclient
 - OS Platform: linux
 - Processor: ps7_cortexa9_0
 - Language: C
 
TemplatesにはLinux Hello Worldを使用します。

1秒毎に192.168.1.12のポート5201にUDPデータ(Hello World)を送信するプログラム(コンソールにもHello Worldを出力)とするため、src/helloworld.cを次のように変更します。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
 int sock;
 struct sockaddr_in addr;
 sock = socket(AF_INET, SOCK_DGRAM, 0);
 addr.sin_family = AF_INET;
 addr.sin_port = htons(5201);
 addr.sin_addr.s_addr = inet_addr("192.168.1.12");
 while(1) {
  printf("Hello World\n");
  sendto(sock, "Hello World", 11, 0, (struct sockaddr *)&addr, sizeof(addr));
  usleep(1000000);
 }
 close(sock);
 return 0;
}
実行/デバッグ
ZYBOとXilink SDKが動作しているWindows PCをEthernetケーブルで接続して、SDカードからLinuxが起動するようになっているZYBOの電源を入れます。
メニューバー -> Run -> Run Configurations(あるいはDebug Configurations)を開きます。Xilinx C/C++ applications (System Debugger)をダブルクリックすると新しいSystem Debuggerが作成されるので、Target SetUpタブでLinux Application Debugを選択し、Newをクリックします。New Target Connectionを以下のように設定します。
- Target Name = udpclient
 - Type = Linux TCF Agent
 - Host = 192.168.1.10 (ZYBOのIPアドレス)
 - Port = 1534
 


Applicationタブのproject NameのBrowseでudpclientを選択するとPathが自動的に設定されます。

Apply後、Runをクリックすると、ZYBO上でプログラムが実行されます。なお、私のWindows PC環境ではUDPが受信できないため、Wiresharkを使用してデバッグを行いました。
ユーザアプリのrootfsへの取り込み
Xilink SDKで作成されたudpclient.elfをUbuntu PCの~/にコピーします。PetaLinuxツールでudpclientというアプリを作成し、udpclient.elfファイルをコピーしてからビルドします。
$ source /opt/pkg/petalinux/settings.sh
$ cd ~/petalinux/project_1/
$ petalinux-create -t apps --template install --name udpclient --enable
$ mv ~/udpclient.elf project-spec/meta-user/recipes-apps/udpclient/files/udpclient
$ petalinux-build
SDカードから実行
SDカードにimage.ubをコピーして、ZYBOを起動するとudpclientコマンドが実行できるようになっています。

ZYBOとUbuntu PCをEthernetケーブルで接続して、Ubuntu PCでUDPを受信したら受信データを表示するプログラム(udpserver.c)を作成して、実行しておきます。
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
 int sock;
 struct sockaddr_in addr;
 char buf[2048];
 sock = socket(AF_INET, SOCK_DGRAM, 0);
 addr.sin_family = AF_INET;
 addr.sin_port = htons(5201);
 addr.sin_addr.s_addr = INADDR_ANY;
 bind(sock, (struct sockaddr *)&addr, sizeof(addr));
 while(1){
  memset(buf, 0, sizeof(buf));
  recv(sock, buf, sizeof(buf), 0);
  printf("%s\n", buf);
 }
 close(sock);
 return 0;
}
$ gcc udpserver.c -o udpserver
ZYBOでudpclientを実行すると、Ubuntu PCでは1秒毎にHello Worldを受信して表示します。

Ubuntu PCのWiresharkでも確認できます。

Discussion