Bir kroki gerçekten nasıl küçültülür


9

Test amacıyla olabildiğince küçük bir taslak yapmak istiyorum. Sorun, ben (boş bir kurulum ve döngü ile) BareMinimum kroki derlemek, ben Uno için 466 bayt ve Leonardo için bir kuyruklu 4,242 olsun. Hiçbir ekstra fonksiyonu olmayan kendi kodunuzu yazmanın herhangi bir yolu var mı (yani Timer0 için millis()ve delay()). Ayrıca Leonardo için klavye / fare işlevlerini devre dışı bırakmak istiyorum.


4
Bu leonardo olarak etiketlenmemeli ve çözülmemelidir (ve bir tahtaya odaklanılmamalıdır)? Bunlar ayrı sorular.
asheeshr

Sadece boş bir derlenmiş taslağın, özellikle yerel USB tabanlı olanlar için birçok pano için büyük olduğuna dikkat çekiyorum
TheDoctor

Ayrıca Leonardo için klavye / fare işlevlerini devre dışı bırakmak istiyorum. ikinci soru.
asheeshr

Yanıtlar:


3

Sen uyarınca özel boards.txt dosyası ile kendi kurul tanımını oluşturmak mümkün olmalıdır https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification . Gördüğüm gibi Leonardo'nun tanımında birkaç usb özelliği var. Ben 4K derlemeleri dahil işlemci tipine değil, bu bayraklar dayanmaktadır umuyoruz.

Boards.txt dosyasının Leonardo'dan yükleme, bootloader bölümlerini ve uno'dan derlemeyi kullanacağı yer.

Tüm bunlar, çekirdek kütüphane derlemesinin USB işlevlerini dahil etmek için işlemciye özgü bayrakları kullanmadığını varsayar.

Eğer böyle bir işe girerseniz. geri göndermek, eminim diğerleri böyle ilgilenen olacaktır.


Geçenlerde bu 4K kullanılan sınırlamayı, aslında UNO'yu en üst düzeye çıkaran ve bir

#if !defined(__AVR_ATmega32U4__)
...

Leonardo'ya sığacak şekilde eskizdeki ekstra özelliklerin büyük bir kısmı.

Bu 4K'nın hala USB'den CD'deki CDC'den Leo'ya Serial.print'i dahil ettiğim için olduğunu (yanlış) varsaymıştım. Ama görüyorum ki boş bir taslağın hafıza dökümünden sonra hala oradalar.

C:\Users\mflaga\AppData\Local\Temp\build8958339595868119500.tmp>avr-objdump -d sketch_feb13a.cpp.elf > sketch_feb13a.cpp.elf.lst

Bu mantıklı. Leonardo hala AVR-DUDE'den 1200 Baud bağlantısını uzaktan yeniden başlatmayı vurmak için USB-CDC istemcisine (4K) ihtiyaç duyduğundan.


Bu nedenle, derlemede USB olmadan özel bir boards.txt yapmak, ayrıca

leonardo.upload.use_1200bps_touch=true

çıkarıldı.

Hedefe yüklendikten sonra, yüklemenin hedefin manuel olarak sıfırlanmasıyla senkronize edilmesi gerekir. Uzaktan yeniden başlatma yeteneği kaybedildiğinden.


Seri.print atlanmış olsa bile 4K'nın neden hala derlendiğine göre güncellenir.
mpflaga

3

Son zamanlarda tam olarak bunu yapmak istedim. Bunu yapmanın güzel bir yolu olmadığından , Stino sublime-text arduino eklentisinin tam olarak bunu yapması için bir yama yazıyorum . Daha sonra kabul edildi, bu yüzden güncel Stino kurulumlarında olmalıdır.

Bu, Stino'ya yeni bir seçenek ekler:

resim açıklamasını buraya girin

Bu modun kullanılması aşağıdaki gibi derleme sonuçları üretir:

Bir Uno için:

İkili çizim boyutu: 172 bayt (maksimum 32256 bayt, yüzde 0,53).
Tahmini bellek kullanımı: 0 bayt (maksimum 1024 bayt, yüzde 0,00).

Leonardo için

İkili çizim boyutu: 240 bayt (maksimum 28672 bayt, yüzde 0,84).
Tahmini bellek kullanımı: 0 bayt (maksimum 2560 bayt, yüzde 0,00).

Aslında programlama yukarıda derlenmiş çıkışı ile leonardo olduğu muhtemelen o kadar kötü bir fikir olabilir Otomatik sıfırlama işlevini bozmaz, ancak olabilir isterseniz. Cevabında bunu kaydettiği için mpflaga'ya şapka ucu.

Bellek raporlarının aslında yanlış olduğunu unutmayın, ancak bu ayrı bir konudur .

Yukarıdakiler için kullanılan kod:

int main()
{
    while (1)
    {

    }
}

Bazı notlar:

  • Sen Hiç gerçekten değil, artık bir "Sketch" yazmıyor do bir çizim yazın. Yazmalısın programları . Dönemi. Arduino wackoslarının ne söylemek istediği umrumda değil, terimleri yeniden tanımlayamıyorlar.
  • Tüm kesme yönetimi manueldir. Bu hayır milis()ya da benzeri anlamına gelir .
  • Sen edebilirsiniz istyorsan ve benzeri arduino seri kütüphaneleri kullanın. Yapmanız gerek #include <Arduino.h>.
  • Siz tanımlayın main. Hiç geri dönmezsin main. Kurulum şeyler istiyorsanız, önce gidiyor while (1).

@jfpoilpret Buna IDE mi diyorsunuz? Makrolarla daha çok not defteri ...
Ron

@ Ron-E Ben bir IDE demiyorum , Arduino IDE onun adı, bu yüzden ismini değmemesine rağmen adını kullandım.
jfpoilpret

2
@FakeName Stack Exchange sitelerinde bozuk dile izin verilmez (bkz: stackoverflow.com/help/behavior ). Bu durumda düzenledim, ancak lütfen gelecekte bu sitede küfür kullanmaktan kaçının. Teşekkürler.
Peter Bloomfield

2

Çiziminize bağlı olmasına rağmen, kodu yöntemlerle tekrar kullanarak boyutu biraz azaltabilirsiniz .

Bu kodu al:

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'da 1.322 bayt. Şimdi biraz küçültelim:

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 bayt. Bu yaklaşık% 10'luk bir düşüş!

Her neyse, bir taslağı büyük ölçüde küçültmese de, bazen sınırın üzerinde iki bayt olduğunuzda veya herhangi bir işlevsellik kaybetmeden başlamak için daha kompakt bir taslak yapmak istediğinizde en kolay yol olabilir. Her durum için değil, ama bazen yararlı buluyorum.


Genellikle, kodu işlevlere çıkarırsanız, derleyici zor işi yapar ve gerisini sizin için doğru yapar.
Cybergibbons

@Cybergibbons [Bunu bilmeyen kullanıcılar için] tanımlayabilir misiniz?
Anonim Penguen

3
Kodu bir işleve ayırırsanız ve verimli olmazsa, genellikle derleyici sizin için sıraya koyacaktır. Ancak, derleyici hiçbir zaman kodu işlevlere bölmez. Bu nedenle, daha fazla işlev yazmak neredeyse her zaman daha iyidir.
Cybergibbons

1
Ayrıca kodu fonksiyonlara sokmak, okumayı ve anlamayı çok daha kolay hale getirir

Doğrudan bağlantı noktası erişimi kullanıldığında, boyut 646 bayta düşürülür. Sadece avr-libc (Arduino çekirdeği yok) kullanarak 220 bayta kadar iner.
Edgar Bonet

0

@annonomus pengueni, emin olabiliriz Kod bilgisayarımdaki bir uno için 1180 bayt flash + 13 bayt RAM içine derlese de, biz onu geliştirebiliriz :) bu yüzden golf meydan kabul ve aynı zamanda birkaç yararlı ipuçları öğrenme.

Adım 1: Değişken gereksinimlerini azaltın. Bir led port için int kullanmak biraz aşırıya kaçmış gibi görünüyor, kesinlikle arduino'da 65535 adresli IO portumuz yok :) Bu yüzden sadece eğlenmek için bir bayta değiştiriyoruz. Daha sonra #define olarak değiştireceğiz, ancak çok büyük değişken türleri kullanmanın etkisini göstereceğiz.

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 bayt + 13 bayt RAM'e derler. Bu, tamsayı yerine bayt için daha az işlem yapılması nedeniyle 8 bayt flaş tasarrufu sağlar. Ben 12 bayt koç beklenir, ama tamam. O kadar değil, ama kaydedilen her bayt iyidir.

2.Adım: Değişken yerine, mantıklı olduğunda tanımlar olarak değiştirin. Örneğin, led bayt gerekli değildir, pim kendiliğinden lehimlenmez.

#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 bytesflash + 11 bayt ram olarak derler. Zaten 38 bayt kaydedildi. Bunun nedeni, int değerini getirmek için gereken daha az kayıt işlemidir. Ayrıca RAM'den 2 bayt kurtardık. (hala baytın neden daha az 1 bayt koç içine derlenmediğini merak ediyorum .....)

3.Adım: Kodu optimize edin. 2 gecikme görüyorum. 1 gecikme olarak değiştirirseniz yer tasarrufu sağlar mıyım, ama LED piminin değerini bulmalı ve değiştirmeliyim. Bunu digitalRead () ile yapabiliriz, ancak yerden tasarruf sağlar mı?

#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 bayt + 11 bayt koç olarak derlenir. Yaşasın! 8 bayt daha. Bu, toplam 46 bayt ve 2 daha az kod satırı yapar.

Ayrıca azalan kod boyutu hakkında başka bir genel ipucu. String sınıfını kullanmayın. BÜYÜK, char dizileri, strcpy (), strcmp () ile nasıl başa çıkacağınızı öğrenin. Tüm sahip olduğunuz bazı temel dize işlemleri ise, String sınıfının kullanımı çoğunlukla hem flash hem de RAM üzerinde alan harcar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.