Gemini Code Assistで2kBマイコン用スケッチを生成できるか?ATTiny202で実験
はじめに
生成 AI によるコード生成は、業務効率化の大きな武器となっています。しかし、リソース制約の厳しい組み込みマイコンの世界でも、同様に活用できるのでしょうか?
今回は、Gemini Code Assistを使って、フラッシュメモリがわずか2kBしかない AVR マイコン「ATTiny202」向けのスケッチ生成を試みました。限られたメモリサイズに収まるコードを生成するために、Gemini Code Assist がどのようなアドバイスをするか検証した結果をご紹介します。
ATTiny202 とは?
ATTiny202は、Microchip 社の AVR マイコンです。非常に小さなパッケージながら、Arduino 環境でプログラミング可能です。
火災警報器も LoRaWAN 化できる!住宅用火災警報器の IoT 化の電子工作という以前のブログで、ひっそりと登場したマイコンです。
- パッケージ:8pin SOIC
- アーキテクチャ:8bit AVR
- フラッシュメモリ:**2kB**
- EEPROM:64B
- RAM:128B
2kB のフラッシュメモリは、Arduino の標準的な Serial 通信ライブラリを使用するだけでかなりの容量を消費してしまいます。この制約のもとで、生成 AI はどこまで役に立つでしょうか?
実験概要
環境準備
実験にあたり、以下の環境を準備しました。
- ボード定義パッケージ:megaTinyCore をインストール
- 書込み装置:jtag2updi を使用
- アナログ入力:PA1(4 番ピン)を使用
- シリアル送信:PA6(2 番ピン)を使用
ハードウェア構成
Gemini Code Assist へのリクエスト
以下のプロンプトで Gemini Code Assist にスケッチ生成を依頼しました。
ATTiny202をarduinoIDEでプログラミングしています。2kBのメモリサイズに入る
プログラムを作る必要があります。ATTiny202の電源電圧は5Vとします。PA1を
アナログ入力に設定し、0Vから5Vの範囲の電圧を3秒毎に測定し、測定値を
シリアル通信でPC上のターミナルソフトに3秒毎に表示します。シリアル通信
のポートは余っている任意のポートで問題なく、PCへのTXのみで問題ありません。
上記を実現するスケッチを生成してください。
最初に生成されたスケッチ
Gemini Code Assist は、以下のスケッチを生成しました。
const int analogInPin = PIN_A1;
const long baudRate = 9600;
void setup() {
Serial.begin(baudRate);
pinMode(analogInPin, INPUT);
analogReference(VDD);
}
void loop() {
int sensorValue = analogRead(analogInPin);
float voltage = sensorValue * (5.0 / 1023.0);
Serial.print("Voltage: ");
Serial.print(voltage);
Serial.println(" V");
delay(3000);
}
一見、要件を満たしているように見えます。しかし…
結果:コンパイルエラー
コンパイルした結果、region ’text’ overflowed by 896 bytes というエラーが発生しました。
つまり、2kB のフラッシュメモリに対して約 3kBのコードが生成されてしまい、サイズオーバーです。
Gemini への追加問い合わせ
サイズオーバーの問題を解決するため、Gemini に以下のように問い合わせました。
スケッチをコンパイルした結果、region `text' overflowed by 896 bytesと
エラーが表示され、サイズオーバしました。サイズをさらに小さくする方法を
教えてください。
Gemini からのアドバイス
Gemini は以下の 3 つの対策を提案しました。
- **対策 1**:浮動小数点演算をなくす(ADC 生データを送信し PC 側で電圧値に変換)
- **対策 2**:整数演算で電圧を計算する(浮動小数点を使わずに mV 単位の整数で計算)
- **対策 3**:コンパイラの最適化設定を変更する(LTO オプションを有効化)
これらの対策を順番に試してみました。
対策 1 の検証:浮動小数点演算の排除
浮動小数点演算を避け、ADC の生データをそのまま送信する方式に変更しました。
結果
1719 バイト(83%)使用 - 成功!
フラッシュメモリ 2kB(2048 バイト)に収まりました。
対策 2 の検証:整数演算での電圧計算
mV 単位の整数で計算する方式を試しました。
結果
1837 バイト(89%)使用 - 成功!
こちらも 2kB に収まりました。対策 1 より若干サイズが大きくなりましたが、PC 側での変換が不要という利点があります。
対策 3 の検証:LTO(Link Time Optimization)
コンパイラの最適化オプション(LTO)を有効にする方法を確認しました。
結果
Arduino IDE 1.8.19 には LTO オプションが見当たらず、この対策は適用できませんでした。
実験結果のまとめ
今回の実験を通じて、以下のことがわかりました。
- 最初に生成されたコードはサイズオーバーとなった
- 問い合わせに対して、適切な対策を複数提案できた
- 対策 1・2 は有効で、実際にメモリ制約をクリアできた
- 対策 3(LTO)は環境によっては適用不可という不正確な面もあった
結論:不正確なアドバイスもあったものの、数回のやり取りで要件を満たすコード(浮動小数点演算を避けたコード)を実装できました。
考察:生成 AI と組み込み開発
今回の実験から、生成 AI を組み込み開発に活用する際のポイントが見えてきました。
有効なケース
- コードの基本構造を素早く生成したい場合
- 最適化のアイデアを得たい場合
- 複数の解決策を比較検討したい場合
注意が必要なケース
- リソース制約が厳しい環境(メモリ、処理速度など)
- 特定の IDE バージョンやツールチェーンに依存する設定
- ハードウェア固有の制約がある場合
生成 AI は「完璧な回答」を期待するのではなく、対話を通じて解決策を探るという使い方が効果的です。特に組み込み開発では、生成されたコードを鵜呑みにせず、必ずコンパイルと動作確認を行うことが重要です。
リソース制約の厳しい組み込み環境でも、生成 AI を上手に活用することで、開発効率を向上させることができそうです。ただし、生成されたコードは必ず検証し、必要に応じて最適化を行うという姿勢が大切ですね。
次回は、RISC-V マイコン CH32V003J4M6でチャレンジしてみたいと思います。乞うご期待!