C言語

C言語で始める組み込み開発入門:WSL環境構築とLED点滅実装

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


スポンサードリンク

1. データ型と演算子

組み込み開発では メモリ効率 が最重要課題です。
C 言語は静的型付けなので、変数のサイズや符号をコンパイル時に確定できます。適切な幅・符号を選ばないと、RAM 数十 KB しかないマイコンで メモリ不足 に陥りやすくなります。

  • 整数型は必ず幅を意識し、int8_tuint16_t のように stdint.h を使うのが安全です。
  • 浮動小数点演算はハードウェアが無い MCU ではソフトエミュレーションになるため、使用は極力避けます。

演算子の優先順位については Zenn の Chapter 5([参照¹])で表形式にまとめられています。基本は * / %+ - より高く、比較演算子はその下位です。

1‑1. 演算子の実践的な使い方

演算子 用途例 メモ
& (ビットAND) レジスタの特定ビットだけ抽出 (reg & 0x01u)
|= (ビットOR代入) 複数フラグを同時に立てる REG |= FLAG_A \| FLAG_B;
<< / >> ビットシフトで割り算・掛け算の代替 value << 3*8 と同等

2. 制御構文

組み込みコードは 状態遷移タイミング処理 が中心です。
if / for / while / switch を過度に入れ子にすると可読性が下がり、最適化もしにくくなるので、ロジックはできるだけフラットに保ちましょう。

  • volatile を付けた変数は最適化対象外になるため、ハードウェアレジスタへのアクセスが必ず実行されます(Zenn Chapter 6[参照²])。
  • ループ内の空ディレイは CPU がフリーランニングで消費電力を上げる原因 になるので、実機ではタイマ割り込みに置き換えることが推奨されます。

3. ポインタとハードウェアレジスタ操作

ポインタは「メモリ上の任意のアドレス」へ直接アクセスできる唯一の手段です。組み込み MCU の GPIO・タイマなどは 物理アドレスにマッピング されているため、volatile ポインタで安全に操作します。

  • アドレスは データシート に必ず記載されているので、コピーミスが起きないようにマクロ化しておくと安心です。
  • *(volatile uint32_t*)addr の形で「読み書き」どちらも同じ構文になる点が、C 言語の大きな利点です。

本節のコードは STM32F4 系列(PC13 LED)を対象にしています。別シリーズの場合はレジスタベースアドレスとビット位置が変わりますので、必ず Reference Manual を確認してください。


4. WSL 上での開発環境構築

4‑1. WSL のインストールと Ubuntu 設定

build-essential に含まれる gcc12 系列(2024 年リリース) がデフォルトです。ただし、Ubuntu のバージョンやリポジトリの更新状況により 11 系列や 13 系列がインストールされることもあります。以下のコマンドで実際のバージョンを必ず確認しましょう。

注意:特定の GCC バージョンが必要な場合は sudo apt install gcc-12 のようにバージョン指定でインストールできます。また、update-alternatives を使ってデフォルトコンパイラを切り替えることも可能です。

4‑2. クロスコンパイラと追加ツール

組み込み向けには ARM 用クロスコンパイラ が必須です。WSL の apt リポジトリから以下のパッケージを取得できます。

Makefile で使用する典型的な設定例は次の通りです。

  • -Osサイズ最適化-ffunction-sections / -fdata-sections--gc-sections の組み合わせで未使用コードを除去します。
  • さらに細かいオプションは Zenn Chapter 7・8([参照³])で解説されています。

5. ビルドフローとデバッグツール設定

5‑1. Makefile の全体像

5‑2. OpenOCD と GDB の連携手順

  • monitor コマンドは OpenOCD に対する指示です。デバッグ中に 安全なリセット を行うのに便利です(Zenn Chapter 6[参照²])。
  • GDB の info registersx/4xb 0x40023830 などでレジスタ内容を直接確認できます。

6. 実践例 ― LED 点滅プログラム

6‑1. STM32F4 (PC13) 用コード

  • static inline にすることで 関数呼び出しオーバーヘッド を除去し、サイズと速度の両方を削減できます。
  • ディレイは CPU が何もしない状態になるため 電力消費が増える 点に注意してください。実機ではタイマ割り込みへ置き換えましょう。

6‑2. Arduino UNO (ATmega328P) 用コード

コンパイルと書き込みの流れは次の通りです。

WSL からシリアルポートへアクセスするには、sudo usermod -a -G dialout $USER でユーザーを dialout グループに追加し、一度ログアウト・再ログインしてください。


7. リソース制約を考慮したベストプラクティス

項目 推奨設定 / コツ
volatile の使用範囲 必要箇所(ハードウェアレジスタ、割込みフラグ)に限定し、最適化の阻害を最小限に。
関数インライン化 小さなユーティリティは static inline にして呼び出しコスト削減。
コードサイズ削減 -Os -ffunction-sections -fdata-sections とリンク時の --gc-sections を必ず使用。
スタック管理 RTOS 未使用なら 1 KB 未満を目安に、関数呼び出し深さとローカル配列サイズを意識。
サイズ確認 ビルド後は arm-none-eabi-sizetext / data / bss をチェックし、必要なら最適化フラグを追加調整。

7‑1. 実行時サイクルの測定例

profile.txt に関数ごとのサイクル使用率が出力されるので、ボトルネック関数の最適化に役立ちます。


8. 次のステップ

  1. 本ガイドで構築した WSL 環境と Makefile を使い、Zenn のサンプルリポジトリ([参照⁴])をクローンしてビルドしてみましょう。
  2. LED 点滅が成功したら GPIO 割込みPWM 出力 へ拡張し、割込みハンドラの書き方やタイマ設定を学習してください。
  3. デバッグ経験を積むことでレジスタマップへの理解が深まり、最終的には FreeRTOS 等のリアルタイム OS を導入した大規模プロジェクトへステップアップできます。

参考文献・リンク

番号 タイトル / 説明 URL
¹ Zenn – 演算子と式の優先順位(Chapter 5) https://zenn.dev/yourname/articles/operator-precedence
² Zenn – volatile と最適化抑止(Chapter 6) https://zenn.dev/yourname/articles/volatile-usage
³ Zenn – GCC のビルドオプション解説(Chapter 7・8) https://zenn.dev/yourname/articles/gcc-options
Zenn – 組み込み C 言語サンプルコード(GitHub リポジトリ) https://github.com/yourname/embedded-c-samples

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-C言語