Как реально сжать эскиз

Я хочу сделать эскиз настолько малым, насколько это возможно, для целей тестирования. Проблема в том, что когда я компилирую эскиз BareMinimum (с пустой установкой и циклом), я получаю 466 байт для Uno и колоссальные 4,242 для Leonardo. Есть ли способ написать собственный код, который не имеет дополнительных функций (а именно Timer0 для millis() и delay()). Я также хотел бы отключить функции клавиатуры /мыши для Леонардо.

9 голосов | спросил TheDoctor 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 05:59:18 +0400000000amFri, 14 Feb 2014 05:59:18 +040014 2014, 05:59:18

4 ответа


3

Вы должны иметь возможность создать собственное определение своей платы с помощью файла custom.txt с помощью https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification . Как я вижу, в определении leonardo есть несколько функций usb. Я надеюсь, что компиляция включения 4K основана на этих флагах, а не на типе процессора.

Если в файле boards.txt будут использоваться разделы загрузки, загрузчика от Leonardo и сборки из uno.

Это все предполагает, что сборка основной библиотеки не использует флаги, специфичные для процессора, для включения функций USB.

Если вы получаете такую ​​работу. post back, я уверен, что другие будут заинтересованы в этом.


Недавно я столкнулся с этим ограниченным использованием 4K на демо-версии библиотеки, которая на самом деле превысила UNO и должна была помещать

#if !defined(__AVR_ATmega32U4__)
...

вокруг большого куска дополнительных функций в эскизе, чтобы поместиться на Леонардо.

Я предположил (ошибочно), что этот 4K был тем, что я все еще включил Serial.print, который, когда над CDC USB на Лео. Но я вижу, что после дампа памяти пустого эскиза они все еще существуют.

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

Это имеет смысл. Поскольку Leonardo по-прежнему требует, чтобы клиент USB-CDC (4K) обнаружил подключение 1200 Baud от AVR-DUDE, чтобы выполнить дистанционную перезагрузку.


Следовательно, создание пользовательского файла board.txt без USB в сборке также должно иметь

leonardo.upload.use_1200bps_touch=true

удалены.

После загрузки на цель это потребует синхронизации загрузки с ручным сбросом цели. Поскольку способность к удаленной перезагрузке теряется.

ответил mpflaga 14 FebruaryEurope/MoscowbFri, 14 Feb 2014 07:27:43 +0400000000amFri, 14 Feb 2014 07:27:43 +040014 2014, 07:27:43
3

Недавно я хотел сделать именно это. Поскольку нет хорошего способа сделать это, я закончил создание патча для Stino возвышенного текстового плагина arduino, чтобы сделать именно это. Впоследствии он был принят, поэтому он должен быть в любых современных установках Stino.

Это добавляет новый вариант для Stino:

введите описание изображения здесь

Использование этого режима дает результаты компиляции, такие как:

Для Uno:

  

Размер двоичного эскиза: 172 байта (максимум 32256 байт, 0,53 процента).
  Предполагаемое использование памяти: 0 байт (максимум 1024 байта, 0,00 процента).

Для леонардо

  

Размер двоичного эскиза: 240 байт (максимум 28672 байта, 0,84 процента).
  Предполагаемое использование памяти: 0 байт (максимум 2560 байт, 0,00 процента).

На самом деле программирование leonardo с приведенным выше скомпилированным выходом возможно плохая идея, так как может сломать автоматический сброс но вы могли бы , если хотите. Hat-tip для mpflaga за то, что заметили это в его ответе.

Обратите внимание, что отчеты о памяти на самом деле неверны, но это отдельная проблема .

Используемый для этого код:

int main()
{
    while (1)
    {

    }
}

Некоторые примечания:

  • Вы больше не пишете «Эскиз», а не то, что вы на самом деле do пишете эскиз. Вы пишете программы . Период. Меня не волнует, что Arduino wackos хотят сказать, они не могут переопределять условия.
  • Все управление прерываниями является ручным. Это означает, что milis() или аналогичный.
  • Вы можете по-прежнему использовать серийные библиотеки arduino и т. д., если хотите. Вам нужно #include <Arduino.h>.
  • Вы определяете main. Вы никогда не возвращаетесь из main. Если вы хотите установить материал, он идет перед while (1).
ответил Connor Wolf 26 FebruaryEurope/MoscowbWed, 26 Feb 2014 11:16:15 +0400000000amWed, 26 Feb 2014 11:16:15 +040014 2014, 11:16:15
2

Хотя это зависит от вашего эскиза, вы можете несколько уменьшить размер повторного использования кода с помощью методов.

Возьмите этот код:

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);
}

1,322 байт на Arduino Uno. Теперь немного сократим его:

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% меньше!

Во всяком случае, хотя он не сильно сокращает , он иногда может быть самым легким путем, когда вы занимаете два байта над лимитом, или просто хотите сделать более компактный эскиз, чтобы начать с без каких-либо функций. Это не для каждой ситуации, но иногда мне это полезно.

ответил Anonymous Penguin 19 MaramWed, 19 Mar 2014 03:43:09 +04002014-03-19T03:43:09+04:0003 2014, 03:43:09
0

@annonomus penguin, мы можем Хотя код компилируется в 1180 байт flash + 13 байт оперативной памяти для uno на моем компьютере, мы можем улучшить его :), так что вызов для гольфа принят, а также несколько полезных советов, поскольку мы участвуем в обучении.

Шаг 1: уменьшить требования к переменной. Использование int для светодиодного порта кажется немного излишним, у нас, конечно же, нет 65535 адресуемых портов ввода-вывода на arduino :) Поэтому мы меняем его на байты просто для удовольствия. Мы изменим его на #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 байт оперативной памяти. Это экономит 8 байт флеш-памяти из-за меньшего количества необходимых операций для байта вместо целого числа. Я ожидал бы 12 батов баранов, но все в порядке. Не так много, но каждый сохраненный байт хорош.

Шаг 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 байт. Сохранено 38 байт. Это связано с меньшим количеством операций с регистром, необходимых для получения значения int. Также мы сохранили 2 байт из ОЗУ. (все еще интересно, почему байт не скомпилировался в 1 байт бара .....)

Шаг 3: оптимизация кода. Я вижу 2 задержки. Интересно, изменил ли я его на 1 задержку, это сэкономит место, но мне нужно выяснить значение светодиодного вывода и переключить его (инвертировать). Мы можем сделать это с помощью функции 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 байт. Ура! еще 8 байтов. Это составляет в общей сложности 46 байт и еще 2 строки кода.

Еще один общий совет по сокращению кодов. Не используйте класс String. Это ОГРОМНОЕ, научиться обращаться с массивами символов, strcpy (), strcmp (). Если все, что у вас есть, есть некоторые основные операции с строкой, использование класса String в основном просто тратит время на флэш-память и оперативную память.

ответил Patrick Deelman 18 FebruaryEurope/MoscowbWed, 18 Feb 2015 16:17:30 +0300000000pmWed, 18 Feb 2015 16:17:30 +030015 2015, 16:17:30

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132