Blog:
Linux C言語アプリケーション開発マニュアル
このブログ記事が廃れたです。BSP 5用のご参考ください。
本マニュアルについて
本マニュアルはトラデックスのCPUモジュール上で動作するC/C++言語アプリケーションを作成する手順を記述しています。
参考:
- http://developer.toradex.com/knowledge-base/board-support-package/openembedded-(core)
- https://developer.toradex.com/knowledge-base/linux-sdks
本マニュアルのPDFダウンロード
1.実行環境
本マニュアルの実行環境は下記です。
仮想化ソフト:VMWARE Player v15.5.6
Host OS: Windows 10 1909
Guest OS: Ubuntu Desktop 18.04LTS 64bit(英語版)
BSP:v3.0.4
CPUモジュール:Colibri-iMX7D 512MB V1.1C
キャリアボード:Colibri 評価ボードRev 3.2 + アクセサリーキット
本マニュアルとは異なるモジュールや評価ボード以外のキャリアボードを使われても大雑把には同じ操作となります。
インターネット接続環境が必要になります。
2.事前準備
本マニュアルはLinux OSイメージ開発マニュアルの内容をすべて終えた状態で進めています。
3.前提知識
Linux OSイメージ開発マニュアルの内容をご理解いただいた状態を前提としています。
4.注意点
オープンソース系を利用した開発に共通することですがすべてを理解しようとするときりがなく開発効率を損ないます。必要なタイミングで必要な知識を身につけるというスタンスで理解することを推奨いたします。
開発環境と実行環境の違いをわかりやすくするためにコマンドの表記の前に下記をつけています。
開発環境(PC)上で入力するコマンド:[ubuntu]$
実行環境(モジュール)上で入力するコマンド:[colibri-imx7]#
コピーについて
本マニュアル内のコマンドなどをコピーした場合、改行が入ったり「-」が抜けてしまうことがあるのでご注意ください。一度テキストエディタなどに張り付けてコピーした内容をご確認ください。
SDKの作成
C言語開発を行うためにOpen Embeddedでターゲットイメージ向けのSDKを作成します。
[ubuntu]$ cd /work/oe-core
[ubuntu]$. export
[ubuntu]$ bitbake console-tdx-image -c populate_sdk
複数のモジュールでSDKを作成している時は下記のようなSDKがすでに存在するというエラーが出るときがあります。
sdkを一度削除してから再度実行してください。
[ubuntu]$ rm -rf /work/oe-core/build/deploy/sdk/*
/work/oe-core/build/deploy/sdk配下にSDKが出力されます。
実行してSDKを展開します。(モジュールやBSPのバージョンによってシェルの名前が変わります。)
[ubuntu]$ /work/oe-core/build/deploy/sdk/tdx-x11-glibc-x86_64-Console-Image-armv7at2hf-neon-toolchain-2.6.4.sh
下記のようにSDKのインストールディレクトリを問われるので入力します。
[ubuntu]$ Enter target directory for SDK (default: /opt/tdx-x11/2.6.4):
本マニュアルではデフォルトの/opt/tdx-x11/2.6.4にインストールしますのでそのままEnterキーを押します。
下記のように問われますので
[ubuntu]$ You are about to install the SDK to "/opt/tdx-x11/2.6.4". Proceed[Y/n]?
Yを入力してEnterキーを押します。
管理者権限で実行しますので途中でパスワードを問われます。パスワードを入力してください。
すでに存在していた場合は下記のように上書きするかどうかを問われますがその場合は一度シェルを停止してシェル実行前にディレクトリを削除しておいたほうが良いです。
If you continue, existing files will be overwritten! Proceed[y/N]?
sudo rm -rf /opt/tdx-x11/2.6.4
最後に下記のような環境変数設定シェルのパスの案内があります。このシェルは後の工程で使用します。
. /opt/tdx-x11/2.6.4/environment-setup-armv7at2hf-neon-tdx-linux-gnueabi
Eclipseのインストール
作業ディレクトリ作成
[ubuntu]$ mkdir -p /work/app && cd /work/app
Eclipse起動にはJavaが必要です。Javaをインストールします。
[ubuntu]$ sudo apt-get -y install openjdk-11-jre
Eclipse(202006バージョン)のサイトからを入手します。(windows10側のブラウザなどで入手)
https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/2020-06/R/eclipse-cpp-2020-06-R-linux-gtk-x86_64.tar.gz
app配下にコピーします。
展開します。
[ubuntu]$ tar -xf ./eclipse-cpp-2020-06-R-linux-gtk-x86_64.tar.gz
Eclipse実行シェル作成
Eclipse起動前にSDK用環境変数を定義する必要があります。またコンパイルオプションも長くなるためSDK用環境変数設定やコンパイルオプションを定義してからEclipseを実行するシェルを作成します。
シェル内にはSDKが出力した環境変数設定シェルの実行も行っています。(長い赤線部分)
(定義する内容は搭載するARMのアーキテクチャやBSPのバージョン、SDK出力ディレクトリなどによって変わります。赤線部分)
[ubuntu]$ cd /work/app/
[ubuntu]$ gedit ./sdk_eclipse.sh
内容は下記です。
-------------------------------------------------------------------------------------------------------------------------------------------- #!/bin/sh SDK_ARM_VER=armv7-a SDK_ARCH=cortex-a7 SDK_ENV_SET=/opt/tdx-x11/2.6.4/environment-setup-armv7at2hf-neon-tdx-linux-gnueabi if [ ! -e ${SDK_ENV_SET} ]; then echo "not found: "${SDK_ENV_SET} exit fi . ${SDK_ENV_SET} export SDK_INCLUDE=${SDKTARGETSYSROOT}/usr/include/ export SDK_OPTIMIZATION="-march=${SDK_ARM_VER} -fno-tree-vectorize -mthumb-interwork -mfpu=neon -mfloat-abi=hard -Wno-poison-system-directories" export SDK_LINKER="-mfloat-abi=hard -L${SDKTARGETSYSROOT}/lib/ -Wl,-rpath-link,${SDKTARGETSYSROOT}/lib/ -L${SDKTARGETSYSROOT}/usr/lib/ -Wl,-rpath-link,${SDKTARGETSYSROOT}/usr/lib/ --sysroot=${SDKTARGETSYSROOT}" ./eclipse/eclipse --------------------------------------------------------------------------------------------------------------------------------------------
各々の設定が改行されていないかを確認してください。改行があるとうまくいきません。
geditで行番号を出す設定にするとわかりやすくなります。行番号を表示するにはgedit起動後画面左上のText Editorで
Preferencesを開きます。
Display Line Numbersにチェックをいれて閉じます。
行番号が表示され各exportが一行で記述されているかどうかが分かりやすくなります。
作成したファイルに実行権限を付与します。
[ubuntu]$ chmod +x ./sdk_eclipse.sh
ワークスペースディレクトリ作成
[ubuntu]$ mkdir ./workspace
Eclipse実行
[ubuntu]$ ./sdk_eclipse.sh
以後Eclipseを起動する場合はこのシェルを使ってください。
Eclipseを実行すると下記のようなワークスペースのディレクトリのパスを指定するウィンドウが表示されますのでワークスペースのパスを設定します。本マニュアルでは/work/app/workspaceにしています。
LaunchをクリックしてEclipseを起動します。
Welcomeと表示されますが必要ないので×ボタンをクリックして消します。
右下のAlways show Welcome at start upのチェックをはずいておけば毎回起動時に表示されることがなくなります。
プロジェクトの作成&ビルド
メニューからFile > New > C++Projectを選択します。
CもしくはC++言語のプログラムを作成するため「C++ Managed Build]を選択してNextをクリックします。
Project Nameを入力します。本マニュアルではTestにしています。
Project typeにEmpty Project、ToolchainsにCross GCCを選択します。
Nextをクリックします。
ここではデフォルト設定のままにします。DebugとRelease設定をもつProjectになります。
Nextをクリックします。
Cross Compiler prefixに「${TARGET_PREFIX}」
Cross Compiler pathに「${OECORE_NATIVE_SYSROOT}/usr/bin/arm-angstrom-linux-gnueabi」を入力してFinishをクリックします。
画面を大きくしないとCross Compiler pathの設定がすべて見えないので画面を最大化して確認してください。
作成したプロジェクトを右クリックしてPropertiesを開きます。
C/C++ Build > Settings > Cross GCC Compiler > Includesで+のアイコンをクリックして下記を設定します。
${SDK_INCLUDE}
同画面のままOptimizationを選択しOther optimization flagsに下記を入力します。
${SDK_OPTIMIZATION}
同画面のままCross G++ Compiler > Includesにも同様に下記を設定します。設定を追加しただけで前回入力したものが入力されていますのでその場合は入力の必要はありません。
${SDK_INCLUDE}
同画面のままOptimizationを選択しOther optimization flagsに下記を入力します。
${SDK_OPTIMIZATION}
同画面のままCross G++ Linker > MiscellaneousのLinker flagsに下記を設定します。
${SDK_LINKER}
ConfigurationをReleaseにしてReleaseの設定にもIncludesやOptimization、Miscellaneousに同様のパラメータを入力します。
すべての設定入力後Apply and Closeをクリックします。
下記のようなリビルドするまで変更が反映されないという警告が出ます。 基本的にプロジェクトの設定変更後はリビルドして反映させますのでRemember my decisionにチェックをいれてYesをクリックします。
プロジェクトを右クリックしNew > Source Fileをクリックしてソースファイルを追加します。
Source fileを入力します。拡張子を必ずつけてください。
Templateはソースコードに付加されるコメントですが本マニュアルではNoneとしています。Finishをクリックします。
ソースコードを入力します。本マニュアルではHello Worldと出力するだけのソースコードを入力しています。
#includeint main(int argc, char ** argv ) { printf("Hello World"); return 0; }
ビルドボタンを押してビルドを行います。Consoleにログが出力されます。正常に終わった場合、青字でログが出力されます。
ビルドログは下記のようになります。
もしエラーが出た場合にはなにかしらの設定ミスがあります。差異に注意してください。
15:20:46 **** Build of configuration Debug for project Test **** make all Building file: ../Test.c Invoking: Cross GCC Compiler arm-tdx-linux-gnueabi-gcc -I"/opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neon-tdx-linux-gnueabi/usr/include/" -O0 -march=ar mv7-a -fno-tree-vectorize -mthumb-interwork -mfpu=neon -mfloat-abi=hard -Wno-poison-system-directories -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"Test.d" -MT"Test.o" -o "Test.o" "../Test.c" Finished building: ../Test.c Building target: Test Invoking: Cross G++ Linker arm-tdx-linux-gnueabi-g++ -mfloat-abi=hard -L/opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neon-tdx-linux-gnueabi/lib/ -Wl,-rp ath-link,/opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neon-tdx-linux-gnueabi/lib/ -L/opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neo n-tdx-linux-gnueabi/usr/lib/ -Wl,-rpath-link,/opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neon-tdx-linux-gnueabi/usr/lib/ --sysroo t=/opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neon-tdx-linux-gnueabi -o "Test" ./Test.o Finished building target: Test 15:20:47 Build Finished. 0 errors, 0 warnings. (took 269ms)
SSH接続設定作成
デバッグに使用するGDBはEthernetで接続してSSHプロトコルを利用してデバッグを行います。
デバッグを行うためにモジュールとSSHで接続できるようにしておく必要があります。
モジュール側の設定を行います。
モジュールにEthernetケーブルを挿入し開発パソコンと同じサブネットに接続します。
Teratermを起動してモジュールを起動します。rootでログインしpasswdコマンドでパスワードを設定します。
本マニュアルではセキュリティを一切気にせず利便性のよいパスワード認証を使い、rootでSSHにログインできるようにします。
あくまでデバッグ目的で設定するだけです。
[colibri-imx7]# passwd
パスワードを2回入力するとパスワードが設定されます。(2回目は確認用)
次にモジュールのIPアドレスの設定を行います。何も設定していない場合はDHCPとなります。
設定ファイル/etc/systemd/network/wired.networkを新規作成します。
[colibri-imx7]# vi /etc/systemd/network/wired.network DHCPの場合 -------------------------------------------------------------------------------------------------------------------------------------------- [Match] Name=eth0 [Network] DHCP=ipv4 --------------------------------------------------------------------------------------------------------------------------------------------
eth0はインターフェイス名です。モジュールやBSPのバージョンによって異なりますのでifconfigコマンドで調べてください。
固定IPの場合
-------------------------------------------------------------------------------------------------------------------------------------------- [Match] Name=eth0 [Network] Address=192.168.100.10/24 Gateway=192.168.100.254 --------------------------------------------------------------------------------------------------------------------------------------------
192.168.100.10/24はIPアドレス192.168.100.10 サブネットマスク255.255.255.0を意味します。
下記コマンドでネットワークマネージャーを再起動します。
[colibri-imx7]# systemctl restart systemd-networkd
ifconfigで設定が反映されているのを確かめます。
[colibri-imx7]# ifconfig
SSH接続確認
開発パソコンから接続できているか確認します。VMwareの設定がデフォルトのNATになっている場合、ホストOSのWindows10で接続できていればUbuntu側で接続できます。接続できない場合は何かしらの設定が間違っている可能性があります。
[ubuntu]$ ping 192.168.100.10
デフォルト設定のOSイメージではSSHサーバーが起動しています。
Teratermの新しい接続でSSH接続をして接続できるかどうか確かめてみます。
Teratermのメニューからファイル> 新しい接続を選択します。
ホスト(T)にはモジュールに設定したIPを入力、サービスはSSHを選択してOKをクリックします。
下記のような警告が出てきます。意図する接続先に間違いありませんので続行をクリックします。
ユーザ名はroot、パスフレーズはpasswdコマンドで設定したパスワードを入力します。
OKをクリックして接続します。
接続できた場合は下記のような画面になります。接続確認ができたらTeratermを終了します。
Ubuntuに戻ります。EclipseのメニューのWindow > Show View > Otherを選択します。
Connectionsを選択してOpenをクリックします。
+マーク(赤枠)のアイコンをクリックしてConnection設定を追加します。
SSHを選択してNextをクリックします。
Connection nameにわかりやすい名前を付けます。
Host, User,PasswordにそれぞれモジュールのIPアドレス、ユーザー名、パスワードを入力してFinishをクリックします。
下記のようなウィンドウが表示されます。Ubuntuのパスワードを入力してUnlockをクリックします。
パスワードの保存を行った場合、パスワード復元用のヒントを作るかどうかを問われます。本マニュアルでは使用しないのでNoをクリックします。
作成したConnection設定を右クリックしてOpen Command Shellを選択します。
モジュールと接続できると下記のような接続先が正しいホストかどうかの警告がでますがYesをクリックします。
既知のホストリストを保存するファイルがないので作成するかどうかを問われます。
Yesをクリックします。
モジュールと接続できるとConsoleでコマンドが打てるようになります。下記ではpwdコマンドを実行しています。
デバッグ設定作成
GDBの初期処理を記述するgdbinitファイルを作成します。本マニュアルでは/work/app/gdbinit に作成します。
[ubuntu]$ gedit /work/app/gdbinit
内容は下記です。(環境変数は使用できません。)
set sysroot /opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neon-tdx-linux-gnueabi set auto-load safe-path /opt/tdx-x11/2.6.4/sysroots/armv7at2hf-neon-tdx-linux-gnueabi
上記2つのコマンドで指定するパスはSDKが出力した環境変数設定シェル内の下記の内容になります。
SDKTARGETSYSROOT
下記コマンドで見ることができます。
[ubuntu]$ cat /opt/tdx-x11/2.6.4/environment-setup-armv7at2hf-neon-tdx-linux-gnueabi | grep SDKTARGETSYSROOT=
デバッグ
プロジェクトエクスプローラに戻り(赤枠をクリック)、プロジェクトを右クリックしDebug As > Debug Configurationsを選択します。
C/C++ Remote Application(青枠)をダブルクリックしデバッグ設定を追加します。赤枠内の設定を行います。
①Projectと②C/C++ Applicationは自動で設定されるままで問題ありません。
Connectionは先ほど作成した設定を選択します。
Browseをクリックします。
接続ができていればモジュール内のホームディレクトリが見えます。(ファイルは何もありません。)そのままOKをクリックします。
自動的にRemote Absolute File Path for C/C++ Applicationに実行パスが設定されます。
Debuggerのタブを開きます。GDB debuggerにgdbのパスを指定します。
本マニュアルでは下記になります。(環境変数は使用できません。)
/opt/tdx-x11/2.6.4/sysroots/x86_64-tdxsdk-linux/usr/bin/arm-tdx-linux-gnueabi/arm-tdx-linux-gnueabi-gdb
上記で指定するパスはSDKが出力した環境変数設定シェル内の下記の設定によります。
OECORE_NATIVE_SYSROOT
上記設定配下の/usr/bin/arm-tdx-linux-gnueabi/arm-tdx-linux-gnueabi-gdbになります。
OECORE_NATIVE_SYSROOTの内容は下記コマンドで見ることができます。
cat /opt/tdx-x11/2.6.4/environment-setup-armv7at2hf-neon-tdx-linux-gnueabi | grep OECORE_NATIVE_SYSROOT=
GDB command fileには先ほど作成したgdbinitのパスを指定します。本マニュアルでは下記になります。
/work/app/gdbinit
Applyをクリック後Debugをクリックします。
Debugが始まると下記のようなDebugウィンドウを開くかどうか問われますのでSwitchをクリックします。
この操作を覚える場合はRemember my decisionにチェックを入れておきます。
デバッグウィンドウが表示されデバッグを行うことができます。
デバッグを行うデバッグウィンドウとソースコードを編集するプロジェクトエクスプローラを切り返すには右上のボタンで切り替えることができます。
Releaseビルドで実行ファイルを作成
デバッグを行いプログラムを完成させた後はリリースビルドで最適化を行ったバージョンの実行ファイルを作成します。
プロジェクトを右クリックBuild Configurations > Set Active > Releaseを選択してReleaseに変更後ビルドボタンを押しビルドを行います。ビルドした実行ファイルは/work/app/workspace/Test/Releaseに格納されています。この実行ファイルをSDカードなどでモジュールに移動し実行することができます。
以上でアプリケーションの開発は終了です。
桐川篤史・岡本無線電機
ガルシアアルバロ・Toradex(トラデックス)