テスト目的で、できるだけ小さいスケッチを作成したいと思います。問題は、BareMinimumスケッチを(空のセットアップとループを使用して)コンパイルすると、Unoに466バイト、Leonardoになんと4,242バイトを取得することです。余分な関数を持たない独自のコード(つまり、millis()
およびのTimer0 delay()
)を作成する方法はありますか?また、Leonardoのキーボード/マウス機能を無効にできるようにしたいと思います。
テスト目的で、できるだけ小さいスケッチを作成したいと思います。問題は、BareMinimumスケッチを(空のセットアップとループを使用して)コンパイルすると、Unoに466バイト、Leonardoになんと4,242バイトを取得することです。余分な関数を持たない独自のコード(つまり、millis()
およびのTimer0 delay()
)を作成する方法はありますか?また、Leonardoのキーボード/マウス機能を無効にできるようにしたいと思います。
回答:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specificationに従って、カスタムboards.txtファイルを使用して独自のボード定義を作成できるはずです。私が見るように、レオナルドの定義にはいくつかのUSB機能があります。4Kのコンパイルのインクルードがプロセッサのタイプではなく、これらのフラグに基づいていることを願っています。
boards.txtがアップロードを使用する場所、Leonardoのブートローダーセクション、およびunoのビルド。
これは、コアライブラリビルドがプロセッサ固有のフラグを使用してUSB関数を含めないことを前提としています。
あなたがそのような働きをするなら。ポストバック、私は他の人がそのようなことに興味を持っていると確信しています。
私は最近、実際にUNOを使い果たしたため、ライブラリデモでこの4K使用制限に遭遇しました。
#if !defined(__AVR_ATmega32U4__)
...
レオナルドに合うように、スケッチの追加機能の大きなチャンクの周り。
この4Kは、LeoのUSBのCDCを介してSerial.printがまだ含まれているためであると(誤って)想定していました。しかし、私は空のスケッチのメモリダンプの後で、それらがまだそこにあるのを見ます。
C:\Users\mflaga\AppData\Local\Temp\build8958339595868119500.tmp>avr-objdump -d sketch_feb13a.cpp.elf > sketch_feb13a.cpp.elf.lst
それは理にかなっています。Leonardoは、リモート再起動をストロークするためにAVR-DUDEから1200ボー接続を検出するために、USB-CDCクライアント(4K)を必要とします。
したがって、ビルドでUSBなしでカスタムboards.txtを作成するには、
leonardo.upload.use_1200bps_touch=true
削除されました。
ターゲットにロードされたら、アップロードをターゲットの手動リセットと同期する必要があります。リモート再起動する機能が失われるので。
私は最近、まさにこれをやりたかったのです。そうするための良い方法がないので、これを正確に行うためにStino sublime-text arduinoプラグイン用のパッチを作成しました。それはその後受け入れられたので、最新のStinoインストールに含まれるはずです。
これにより、Stinoに新しいオプションが追加されます。
このモードを使用すると、次のようなコンパイル結果が生成されます。
Unoの場合:
バイナリスケッチサイズ:172バイト(最大32256バイト、0.53パーセント)。
推定メモリ使用量:0バイト(最大1024バイトのうち、0.00%)。
レオナルドのために
バイナリスケッチサイズ:240バイト(最大28672バイトのうち、0.84%)。
推定メモリ使用量:0バイト(最大2560バイトのうち、0.00%)。
上記のコンパイルされた出力を使用して実際にレオナルドをプログラミングすることは、自動リセット機能を破壊する可能性があるため、おそらく悪い考えですが、必要に応じて可能です。mpflagaの回答でこれを指摘したことに対するヒント。
メモリレポートは実際には正しくありませんが、それは別の問題です。
上記に使用されるコードは次のとおりです。
int main()
{
while (1)
{
}
}
いくつかのメモ:
milis()
または類似しないことを意味します。#include <Arduino.h>
ます。main
。から戻ることはありませんmain
。あなたがセットアップのものを望むなら、それはの前に行きますwhile (1)
。スケッチにもよりますが、メソッドでコードを再利用することにより、サイズを多少小さくすることができます。
このコードを取ります:
int led = 13;
int val;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
val = digitalRead(10);
}
Arduino Unoで1,322バイト。それを少し縮小しましょう:
int led = 13;
int val;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
for(uint8_t i = 0; i < 8; i++) {
blink(HIGH);
blink(LOW);
}
val = digitalRead(10);
}
void blink(uint8_t state) {
digitalWrite(led, state); // turn the LED to the right state
delay(1000); // wait for a second
}
1,194バイト。これは約10%の減少です。
とにかく、それはスケッチを大きく縮小しませんが、制限を2バイト超えている場合や、機能を失うことなく最初からよりコンパクトなスケッチを作成したい場合は、これが最も簡単なルートになることがあります。すべての状況に対応できるわけではありませんが、役立つ場合もあります。
@annonomusペンギン、できます。コードは1180バイトのフラッシュと13バイトのRAMにコンパイルされますが、コンピュータ上でunoを実現できますが、それを改善することができます。学習。
ステップ1:変動要件を減らす。LEDポートにintを使用するのは少々やり過ぎに思われますが、arduinoには65535のアドレス可能なIOポートがないのは確かです。後で#defineに変更しますが、大きすぎる変数タイプを使用した場合の影響を示します。
byte led = 13;
int val;
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
blink();
val = digitalRead(10);
}
void blink() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
1172バイト+ 13バイトのRAMにコンパイルします。これにより、整数の代わりにバイトに必要な操作が少なくなるため、8バイトのフラッシュが節約されます。12バイトのRAMが必要ですが、大丈夫です。それほど多くはありませんが、保存されたすべてのバイトは良好です。
ステップ2:意味のあるときに変数を定義に切り替えます。たとえば、リードされたバイトは不要で、ピンはハンダ付けされません。
#define LED 13
int val;
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
blink();
val = digitalRead(10);
}
void blink() {
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
1142バイトのフラッシュ+ 11バイトのRAMにコンパイルします。すでに38バイトが保存されています。これは、int値をフェッチするために必要なレジスタ操作が少ないためです。また、RAMから2バイトを節約しました。(バイトが1バイト少ないRAMにコンパイルされなかった理由はまだ疑問です...)
ステップ3:コードを最適化します。2つの遅延が発生します。スペースを節約するために1遅延に変更するかどうかは疑問ですが、LEDピンの値を把握し、トグル(反転)する必要があります。それはdigitalRead()で実行できますが、スペースを節約できますか?
#define LED 13
int val;
void setup() {
pinMode(LED, OUTPUT);
}
void loop() {
blink();
val = digitalRead(10);
}
void blink() {
digitalWrite(LED, !digitalRead(LED)); // toggle the led based on read value
delay(1000); // wait for a second and spare yourself the other delay
}
1134バイト+ 11バイトのRAMにコンパイルします。わーい!さらに8バイト。これにより、合計で46バイト、コードが2行少なくなります。
コードサイズを小さくするためのもう1つの一般的なヒント。Stringクラスは使用しないでください。それは巨大です、char配列、strcpy()、strcmp()を処理する方法を学びます。基本的な文字列操作がすべてある場合、Stringクラスの使用は、ほとんどの場合、フラッシュとRAMの両方のスペースを無駄にするだけです。