Okawa Yusuke
Okawa Yusuke

饂飩人(うどんちゅ)

About Me

高専ロボコンに制御班として参加していました。ものづくり全般が好きで、Arduino を使った組み込みの開発を行っており、主に CPU, OS, コンパイラ等の低レイヤ系に興味があります。最近は Web 系もやってます。

興味・関心
  • クラス設計・ライブラリ設計
  • C++ コンパイル時処理
  • お散歩🚴
Blog
Arduino でサブディレクトリにファイル分割する方法

Arduino でサブディレクトリにファイル分割する方法

ソフトウェアを開発する際、ソースコードが増えてくるとファイル分割し、さらにはサブディレクトリに整理したくなることがあるかと思います。 目的としては、ビルド時間の短縮や可読性アップなどでしょうか。私の場合、特に大きなライブラリ(SDカード関連など)を使用する際は、ラッパーを介して呼び出すようにしています。具体的には、ライブラリのヘッダはラッパーを定義したソースファイルにのみインクルードし、メインソースファイルにはライブラリ実装が直接含まれないようにします。するとライブラリヘッダを含むソースファイルのコンパイル結果を再利用できるため、ビルド時間を大幅に短縮することができます。 それはさておき Arduino 君は癖がすごいので、ノリでサブディレクトリを作成しても全然ビルドできません。そこで Arduino の仕様を探索しましたので対処策をいざ投下 TL;DR プロジェクトのルートディレクトリに src ディレクトリを作成し、その中にサブディレクトリを配置します。こうするとサブディレクトリ下に配置したソースファイルもビルド対象に含んでくれます。 project ├── project.ino └── src <-- これだけ! ├── common │ ├── vector2d.hpp │ └── vector2d.cpp ├── hardware │ ├── motor.hpp │ └── motor.cpp └── network ├── mdns.hpp ├── mdns.cpp ├── http_server.hpp └── http_server.cpp ヘッダをインクルードする際は各ファイルからの相対パスでインクルードします。

シリアライザを作る

シリアライザを作る

シリアライザを作った際のメモです。 シリアライザとは、構造体等のオブジェクトをバイト列に変換する機能です。通信関係のライブラリを作る際に必要になったため自作しました。 実装する際には、環境の違いによって変換後のバイト列の順序やサイズが異なる可能性があるためなかなか大変です。オブジェクトをバイト列に変換した際、CPU のエンディアンや ABI、コンパイラの仕様によって、データの配置やパディングの有無が変わることがあります。 実装時に気をつける環境の違いによる影響: エンディアンが異なる点 浮動小数点型のサイズが異なる点 構造体のパディングサイズが異なる点 実装したこと: メンバ変数を列挙する黒魔術(パディングによるサイズの違いの対策) シリアライズ後のサイズをコンパイル時に算出する エンディアン変換 浮動小数点型のサイズが異なる問題の対策 エンディアン オブジェクトをメモリに配置する際のバイト列の並び順のことです。主にビッグエンディアンとリトルエンディアンの 2 種類があります。 ビッグエンディアンは上位バイトから下位バイトに向かって配置されます。インターネッツの世界はこれです。イメージ: mem[offset + 0] = obj[0] mem[offset + 1] = obj[1] mem[offset + 2] = obj[2] リトルエンディアンは下位バイトから上位バイトに向かって配置されます。最初に知った時は驚きました。一般的に普及している CPU はリトルエンディアンです。イメージ:

Product