Armadillo標準ガイド ソフトウェア開発編

~組み込みLinuxの導入から製品化まで~


目次

1. はじめに
1.1. 対象読者
1.2. 表記について
1.2.1. コマンド入力例
1.2.2. アイコン
1.3. サンプルソースコード
1.4. 困った時は
1.5. お問い合わせ先
1.6. 商標
1.7. ライセンス
1.8. 謝辞
2. 注意事項
3. 開発環境の整備と運用
3.1. ATDE7にソフトウェアを追加する
3.1.1. ソフトウェアが含まれるパッケージを検索する
3.1.1.1. Debianパッケージページで検索する
3.1.1.2. aptコマンドで検索する
3.1.1.3. すでにインストールされているパッケージから逆引きする
3.1.2. パッケージをインストールする
3.2. ATDE7にクロス開発用ライブラリをインストールする
4. Linuxシステムの仕組みと運用、管理
4.1. コマンドの使い方を調べる
4.2. ユーザー管理
4.2.1. 特権ユーザーと一般ユーザー
4.2.2. ユーザーの追加と削除
4.2.3. ユーザーとグループ
4.3. ファイルの操作
4.3.1. ファイルの種類
4.3.2. ファイルの属性情報(inode)
4.3.3. ファイルシステムとパス
4.3.4. ファイルの所有権とパーミッション
4.3.5. デバイスファイルの管理
4.4. プログラムとプロセス
4.5. シグナル
4.6. プロセス間通信
4.7. 端末
4.7.1. シリアル端末
4.7.2. コンソール端末
4.7.3. 擬似端末
4.8. 時間の管理
4.8.1. タイムゾーン
4.8.2. 時刻を正確に保つ
4.8.3. タイマーの分解能
4.9. ロケール
4.10. ネットワーク
4.10.1. ネットワークインターフェース
4.10.2. IPアドレスとポート番号
4.10.3. ホスト名とリゾルバ
4.10.4. ネットワークの状態を調べる
5. シェルスクリプトプログラミング
5.1. シェルの種類
5.2. シェルスクリプトの書き方
5.3. シェルの構文
5.3.1. 基本的なコマンドの実行方法
5.3.2. 変数
5.3.3. 環境変数
5.3.4. パラメータ
5.3.5. クォート
5.3.6. 展開
5.3.7. 終了ステータス
5.3.8. 入出力の扱い
5.3.8.1. 標準入出力
5.3.8.2. リダイレクト
5.3.8.3. パイプ
5.3.8.4. ヒアドキュメント
5.3.9. 様々なコマンドの実行方法
5.3.9.1. 単純なコマンド
5.3.9.2. パイプライン
5.3.9.3. リスト
5.3.9.4. 複合コマンド
5.3.9.5. バックグラウンド実行
5.3.10. 制御構文
5.3.10.1. if文
5.3.10.2. case文
5.3.10.3. for文
5.3.10.4. while文
5.3.11. 関数
6. C言語による実践プログラミング
6.1. C言語プログラミングのためのツールたち
6.1.1. Cコンパイラ: gcc
6.1.1.1. 動作全体に関わるオプション
6.1.1.2. 警告オプション
6.1.1.3. 最適化オプション
6.1.1.4. 処理対象となるディレクトリやファイルを追加するオプション
6.1.1.5. プロセッサ固有のオプション
6.1.2. クロスツールチェーン
6.1.2.1. プレフィックス
6.1.3. makeとmakefile
6.1.3.1. make
6.1.3.2. makefileへのルールの記述
6.1.3.3. makefileでの変数の使用
6.1.3.4. makefileで使用される暗黙のルールと定義済み変数
6.1.3.5. 変数の外部定義とオーバーライド
6.1.3.6. 条件文
6.1.3.7. make動作の実際
6.2. C言語プログラミングの復習
6.2.1. コマンドライン引数の扱いと終了ステータス
6.2.2. 終了処理
6.2.3. エラー処理
6.2.4. 共通ヘッダファイル
6.3. ファイルの取り扱い
6.3.1. テキストファイルを扱う
6.3.2. 設定ファイルに対応する
6.3.3. バイナリファイルを扱う
6.4. デバイスの操作
6.4.1. デバイスファイルを使う
6.4.2. sysfsファイルシステムを使う
6.5. シリアルポートの入出力
6.5.1. シリアルエコーサーバー
6.5.2. 改行コードの違いを吸収する
6.5.3. より効率的な入出力方法
6.6. ネットワークを使う
6.6.1. TCP/IP
6.6.2. TCP/IPでHello!
6.6.3. ネットワークエコーサーバー
6.7. プログラムをデバッグする
6.7.1. gdbによるデバッグ
6.7.2. straceでシステムコールをトレースする
6.7.3. メモリ破壊やメモリリークのデバッグ
6.7.3.1. Electric Fenceを使ったメモリ破壊検出
6.7.3.2. MemWatchを使ったメモリリーク検出
7. Python言語による実践プログラミング
7.1. Python実行環境をインストールする
7.2. ファイルの取り扱い
7.2.1. テキストファイルを扱う
7.2.2. 設定ファイルに対応する
7.2.3. JSONファイルを扱う
7.2.4. XMLファイルを扱う
7.3. ネットワークを使う
7.3.1. Python版TCP/IPでHello!
7.3.2. HTTP通信を行う
7.3.2.1. HTTPサーバーを準備する
7.3.2.2. HTTPサーバーに接続する
7.4. データベースを使う
7.5. プログラムをデバッグする
7.5.1. トレースバックを読む
7.5.2. デバッガを使う
8. 組み込みシステム構築の定石
8.1. 起動時にコマンドを自動実行する
8.1.1. systemdとは
8.1.2. 自動起動するコマンドの作成
8.1.3. Unitファイルの作成
8.1.4. 自動起動の設定
8.1.5. 自動起動の解除
8.1.6. 順序関係のあるコマンドの自動起動
8.2. 定期的にコマンドを実行する
8.2.1. systemdで定期実行する
8.3. 不具合発生時の自動再起動
8.3.1. systemdによるプロセスの自動再起動
8.3.2. ウォッチドッグタイマーによるシステムの再起動
8.4. ログ管理
8.4.1. ログファイルのローテーション
8.4.2. ログをリモートサーバーに送る
8.5. 外部ストレージのデータを守る
8.5.1. データがストレージに書き込まれたことを保証する
8.5.2. 不意な電源断への対応
8.6. ファイアーウォールを設定する
8.6.1. すべてのパケットを破棄する
8.6.2. SSHを許可する
8.6.3. HTTPSを許可する
8.6.4. 設定値を保存する
8.7. SSHのセキュリティ設定を見直す
8.7.1. パスワードの代わりにRSA公開鍵認証を使う
8.7.2. 使用するポートを変更する
8.8. ソフトウェアアップデート
8.8.1. Gitによるソースコードの管理
8.8.1.1. Gitリポジトリの作成
8.8.1.2. ベースとなるソースコードの登録
8.8.1.3. ソースコードの修正
8.8.1.4. ベースとなるソースコードの更新
8.8.1.5. 更新後のベースとなるソースコードにソースコードの修正を適用
8.8.2. Armadilloのソフトウェア更新における2つの考え方
8.8.3. インストールディスクを使用してのアップデート
8.8.4. インターネットを使用してのアップデート
8.8.4.1. APT でインストールしたソフトウェアのアップデート
8.8.4.2. APT でインストールしたソフトウェア以外のソフトウェアのアップデート
8.9. PCとArmadillo間でファイルを共有する
8.9.1. sambaをインストールする
8.9.2. sambaを設定する
8.9.3. Windowsからアクセスする
8.9.4. ATDEからアクセスする

図目次

1.1. クリエイティブコモンズライセンス
3.1. apt searchによるパッケージの検索
3.2. lsコマンドが含まれているパッケージを調べる
3.3. apt installによるパッケージのインストール
3.4. armhfアーキテクチャをdpkgのarchitectureリストに追加する
3.5. dpkgのarchitectureリストを表示する
3.6. armhf用のlibboostの開発用パッケージのインストール
3.7. Armadilloへのlibboostのインストール
4.1. --helpオプションでコマンドの使用方法を調べる
4.2. コマンドの使用方法を調べる(--helpオプションをサポートしていない場合)
4.3. catコマンドの使用方法を調べる
4.4. ユーザーの切り替え(suコマンド)
4.5. 一時的なユーザーの切り替え(sudoコマンド)
4.6. ユーザーの追加(useraddコマンド)
4.7. パスワードの設定(passwdコマンド)
4.8. ユーザーの削除(userdelコマンド)
4.9. ログインできないユーザーとしてコマンドを実行する(sudoコマンド)
4.10. グループを追加する(groupaddコマンド)
4.11. ユーザーが所属するグループを変更する(usermodコマンド)
4.12. ユーザーを別のグループにも所属させる(usermodコマンド)
4.13. ユーザーが所属しているグループを確認する(groupsコマンド)
4.14. inodeが持つ情報を確認する(ls -lコマンド)
4.15. ファイルのパーミッションを変更する(chmodコマンド)
4.16. umaskと新規作成時のファイルパーミッション
4.17. etc/shadowファイルとpasswd実行ファイルのパーミッション
4.18. /tmpディレクトリのパーミッション
4.19. デバイスファイルの例
4.20. デバイスファイルの作成(mknodコマンド)
4.21. プロセス一覧の確認(psコマンド)
4.22. シリアルポートの読み書き
4.23. シリアルポートの設定確認(sttyコマンド)
4.24. 端末が使用しているttyデバイスの確認(ttyコマンド)
4.25. カーネルパラメーターの確認(proc/cmdlineファイル)
4.26. Gnome端末でのttyデバイス
4.27. システムクロックの参照(dateコマンド)
4.28. ハードウェアクロックの参照(hwclockコマンド)
4.29. システムクロックの参照(タイムゾーンを指定)
4.30. システムクロックをハードウェアクロックに設定する(UTC)
4.31. システムクロックをハードウェアクロックに設定する(ローカルタイム)
4.32. adjtimexによるシステムクロックの補正1: systemd-timesyncdの停止
4.33. adjtimexによるシステムクロックの補正2: adjtimexのインストール
4.34. adjtimexによるシステムクロックの補正3: ntpdateによる補正データの測定
4.35. adjtimexによるシステムクロックの補正4: 補正データの設定と確認
4.36. システムでサポートされているすべてのロケールを得る(locale -aコマンド)
4.37. 現在のロケールを確認する(localeコマンド)
4.38. ロケールを指定してdateコマンドを実行
4.39. ipコマンドの構文
4.40. helpの表示する(ipコマンド)
4.41. ネットワークインターフェースの状態を取得する(ipコマンド)
4.42. 特定のネットワークインターフェースの状態を取得する(ipコマンド)
4.43. ネットワークインターフェースからIPアドレスを削除する(ipコマンド)
4.44. ネットワークインターフェースにIPアドレスを設定する(ipコマンド)
4.45. networking.serviceを再起動する
4.46. ATDE7のinterfacesファイル
4.47. 使用中のポート番号を調べる(ssコマンド)
4.48. ホスト名を調べる(hostnameコマンド)
4.49. /etc/hostsファイル
4.50. ネットワークの到達確認: 成功(pingコマンド)
4.51. ネットワークの到達確認: 失敗(pingコマンド)
5.1. for文の例1
5.2. for文の例2
5.3. シェルスクリプトの例(example.sh)
5.4. シェルスクリプト実行例
5.5. シェルでコマンドを実行する
5.6. シェルでコマンドを実行する(空白を含む引数)
5.7. 変数の例
5.8. 算術演算の例
5.9. 配列の例
5.10. すべての環境変数の表示
5.11. 環境変数の設定
5.12. クォートの例
5.13. チルダ展開の例
5.14. コマンド置換の例
5.15. 終了ステータスの例
5.16. 出力のリダイレクト
5.17. 出力のリダイレクト(追記)
5.18. 標準エラー出力のリダイレクト
5.19. 標準出力のリダイレクト
5.20. 複数の出力のリダイレクト
5.21. 標準出力と標準エラー出力を同じファイルにリダイレクト
5.22. 出力を/dev/nullにリダイレクト
5.23. 入力のリダイレクト
5.24. パイプ
5.25. パイプの例
5.26. ヒアドキュメントの文法
5.27. ヒアドキュメントの例
5.28. ヒアドキュメントの例(クォート)
5.29. 単純なコマンドの文法
5.30. パイプラインの文法
5.31. リストの文法
5.32. サブシェルの文法
5.33. グループコマンドの文法
5.34. 算術評価の文法
5.35. 条件式評価の文法
5.36. if文の構文
5.37. if文の例(if_sample.sh)
5.38. case文の構文
5.39. case文の例(case_sample.sh)
5.40. for文の構文
5.41. for文の例1(for_sample1.sh)
5.42. for文の例2(for_sample2.sh)
5.43. for文の例3(for_sample3.sh)
5.44. while文の構文
5.45. while文の例(while_sample.sh)
5.46. 関数の構文
5.47. 関数の例(function_sample1.sh)
5.48. function_sample1.shの実行結果
5.49. 関数の例(function_sample2.sh)
5.50. function_sample2.shの実行結果
5.51. 関数の例(function_sample3.sh)
5.52. function_sample3.shの実行結果
5.53. 関数の例(function_sample4.sh)
5.54. function_sample4.shの実行結果
6.1. ルールの記述方法
6.2. ルールの記述方法2
6.3. makefileの実例
6.4. makefileの実例: 実行結果
6.5. オーバーライドの発生例
6.6. 基本的なmakefile
6.7. 複数ファイルを扱うmakefile
6.8. すべてのパラメータを表示するプログラム(show_arg.c)
6.9. show_argの実行結果
6.10. greetingの動作
6.11. greeting.c
6.12. fdump.c
6.13. fdumpの実行結果
6.14. エラー内容表示とFAILURE終了するためのヘッダ(exitfail.h)
6.15. CSVファイルの内容を表示するプログラム(dispcsv1.c)
6.16. dispcsv1の実行結果
6.17. CSVファイルの内容を表示するプログラムのconfファイル対応版 (dispcsv2.c)
6.18. pkg-configとGLibのインストール
6.19. dispcsv2のためのMakefile
6.20. dispcsv2の実行結果
6.21. BMPファイル形式構造定義ヘッダファイル(bitmap.h)
6.22. BMP形式画像ファイルのコンソール表示プログラム(dispbmp.c)
6.23. dispbmp の実行結果
6.24. シェルからLEDを点灯/消灯する
6.25. LEDの点灯/消灯を行うプログラム(led_on_off.c)
6.26. led_on_off の実行例
6.27. シリアルエコーサーバー(serial_echo_server1.c)
6.28. serial_echo_server1の実行例
6.29. 改行コード変換を行うシリアルエコーサーバー(serial_echo_server2.c)
6.30. 改行コード変換を行うシリアルエコーサーバー(serial_echo_server3.c)
6.31. TCP/IPプログラムの基本的な流れ
6.32. ネットワークでHello!を返すサーバー (network_hello_server.c)
6.33. network_hello_serverの実行結果
6.34. ネットワークエコーサーバー (network_echo_server1.c)
6.35. network_echo_server1の実行結果
6.36. network_echo_server1へのtelnet(Windows)
6.37. ネットワークエコーサーバー (network_echo_server2.c)
6.38. 1から100までの和を計算するプログラム (sum.c)
6.39. sumの実行結果
6.40. メモリ破壊を行うプログラム (mem_corruption.c)
6.41. メモリリークが発生するプログラム (mem_leak.c)
7.1. pythonバージョン3のインストール
7.2. pythonの動作確認
7.3. pipのインストール
7.4. CSVファイルの内容を表示するプログラム(dispcsv1.py)
7.5. dispcsv1.pyの実行結果
7.6. CSVファイルの内容を表示するプログラムのconfファイル対応版 (dispcsv2.py)
7.7. dispcsv2.confを編集したdispcsv2.pyの実行結果
7.8. CSVファイルの内容を表示するプログラムのJSON形式のconfファイル対応版 (dispcsv3.py)
7.9. dispcsv3.jsonを編集したdispcsv3.pyの実行結果
7.10. CSVファイルの内容を表示するプログラムのXML形式のconfファイル対応版 (dispcsv4.py)
7.11. ネットワークでHello!を返すサーバー Python版(network_hello_server.py)
7.12. network_hello_server.pyの実行結果
7.13. network_hello_serverへのtelnet
7.14. 取得するindex.htmlファイル(index.html)
7.15. HTTPサーバーにアクセスするプログラム(http_access.py)
7.16. http_access.pyの実行結果
7.17. パラメータ付きでHTTPサーバーにアクセスするプログラム(http_access_param.py)
7.18. パラメータ付きでHTTPサーバーにアクセスするプログラム(http_access_post.py)
7.19. データベースを操作するプログラム(handling_database.py)
7.20. handling_database.pyの実行結果(addサブコマンド)
7.21. handling_database.pyの実行結果(showサブコマンド)
7.22. handling_database.pyの実行結果(updateサブコマンド)
7.23. handling_database.pyの実行結果(deleteサブコマンド)
7.24. 0除算を行う可能性のあるプログラム (dividezero.py)
7.25. dividezero.pyの実行結果
7.26. 配列の範囲外へアクセスする可能性のあるプログラム (outofrange.py)
7.27. outofrange.pyの実行結果
7.28. 1から100までの和を計算するプログラム (sum.py)
7.29. sum.pyの実行結果
8.1. シェルスクリプトの実装内容(system_init_test.sh)
8.2. Unitファイルの実装内容(system_init_test.service)
8.3. シェルスクリプトの実装内容(system_init_test_a.sh)
8.4. シェルスクリプトの実装内容(system_init_test_b.sh)
8.5. Unitファイルの実装内容(system_init_test_a.service)
8.6. Unitファイルの実装内容(system_init_test_b.service)
8.7. シェルスクリプトの実装内容(system_init_test_a.sh)
8.8. Unitファイルの実装内容(system_init_test_a.service)
8.9. Unitファイルの実装内容(system_init_test_a.timer)
8.10. sshd_configの修正箇所
8.11. sshd_configの修正箇所(ポート番号)
8.12. 編集前のinclude/configs/armadillo-640.h(末尾のみ抜粋)
8.13. 編集後のinclude/configs/armadillo-640.h(末尾のみ抜粋)
8.14. /lib/systemd/system/apt-daily.timer
8.15. /lib/systemd/system/apt-daily-upgrade.timer
8.16. /lib/systemd/system/apt-daily.service
8.17. /lib/systemd/system/apt-daily-upgrade.service
8.18. 毎日4:00に処理を実行するUnitファイルの実装内容(web_image_update.service)
8.19. 毎日4:00に処理を実行するUnitファイルの実装内容(web_image_update.timer)
8.20. Webサーバーにあるイメージファイルでフラッシュメモリをアップデートするスクリプト(web_software_update.sh)