테스트 목적으로 가능한 한 작은 스케치를 만들고 싶습니다. 문제는 빈 설정과 루프로 BareMinimum 스케치를 컴파일 할 때 Uno의 경우 466 바이트, Leonardo의 경우 4,242 바이트입니다. 추가 기능이없는 자체 코드를 작성할 수있는 방법이 있습니까 (즉, Timer0 for millis()
및 delay()
). 또한 Leonardo의 키보드 / 마우스 기능을 비활성화하고 싶습니다.
테스트 목적으로 가능한 한 작은 스케치를 만들고 싶습니다. 문제는 빈 설정과 루프로 BareMinimum 스케치를 컴파일 할 때 Uno의 경우 466 바이트, Leonardo의 경우 4,242 바이트입니다. 추가 기능이없는 자체 코드를 작성할 수있는 방법이 있습니까 (즉, Timer0 for millis()
및 delay()
). 또한 Leonardo의 키보드 / 마우스 기능을 비활성화하고 싶습니다.
답변:
https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification에 따라 사용자 정의 boards.txt 파일을 사용하여 자체 보드 정의를 작성할 수 있어야합니다 . 내가 알다시피 leonardo의 정의에는 몇 가지 USB 기능이 있습니다. 4K의 컴파일 포함은 프로세서 유형이 아닌 이러한 플래그를 기반으로하기를 바랍니다.
boards.txt가 업로드를 사용하는 경우 Leonardo의 부트 로더 섹션과 uno의 빌드입니다.
이것은 핵심 라이브러리 빌드가 프로세서 특정 플래그를 사용하여 USB 기능을 포함하지 않는다고 가정합니다.
그런 일을하면. 다시 게시, 나는 다른 사람들이 그런 관심이있을 것이라고 확신합니다.
최근에 실제로 UNO를 최대한 활용하고
#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 Baud 연결을 감지하기 위해 여전히 USB-CDC 클라이언트 (4K)를 필요로합니다.
따라서 빌드에서 USB없이 사용자 정의 boards.txt를 만들려면
leonardo.upload.use_1200bps_touch=true
제거되었습니다.
대상에 일단로드되면 업로드를 대상의 수동 재설정과 동기화해야합니다. 원격 재부팅 기능이 손실됩니다.
나는 최근에 이것을 정확하게하고 싶었다. 그렇게 할 수있는 좋은 방법이 없기 때문에 Stino sublime-text arduino 플러그인이 정확히 이것을 수행 하는 패치 를 작성했습니다 . 이후에 승인되었으므로 최신 Stino 설치에 있어야합니다.
이것은 Stino에 새로운 옵션을 추가합니다 :
이 모드를 사용하면 다음과 같은 컴파일 결과가 생성됩니다.
우노의 경우 :
이진 스케치 크기 : 172 바이트 (최대 32256 바이트, 0.53 %)
예상 메모리 사용 : 0 바이트 (최대 1024 바이트, 0.00 %)
레오나르도
이진 스케치 크기 : 240 바이트 (최대 28672 바이트, 0.84 %)
예상 메모리 사용 : 0 바이트 (최대 2560 바이트, 0.00 %)
실제로 컴파일 된 출력으로 leonardo를 프로그래밍 하는 것은 아마도 자동 재설정 기능을 중단 할 수 있기 때문에 좋지 않은 생각 일 수 있지만 원한다면 할 수 있습니다. 그의 답변에 이것을 지적 해 주신 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으로 컴파일되지만 개선 할 수 있습니다 :) 그래서 골프 도전과 우리가 사업을하고 있기 때문에 유용한 팁 배우기.
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 바이트의 램을 기대하지만 괜찮습니다. 그렇게 많지는 않지만 저장된 모든 바이트가 좋습니다.
2 단계 : 변수를 의미있는 시점으로 정의로 전환 예를 들어, led 바이트는 필요하지 않으며 핀 자체는 풀리지 않습니다.
#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 값을 페치하는 데 필요한 레지스터 조작이 적기 때문입니다. 또한 RAM에서 2 바이트를 저장했습니다. (아직 바이트가 왜 1 바이트 미만의 램으로 컴파일되지 않았는지 궁금합니다 .....)
3 단계 : 코드 최적화 두 가지 지연이 있습니다. 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 바이트 램으로 컴파일합니다. 예이! 다른 8 바이트. 이는 총 46 바이트와 2 줄의 코드 줄입니다.
코드 크기를 줄이는 또 다른 일반적인 팁. String 클래스를 사용하지 마십시오. char 배열, strcpy (), strcmp ()를 다루는 방법을 배우십시오. 기본 문자열 작업이 모두 있다면 String 클래스의 사용은 대부분 플래시와 RAM 모두에서 공간을 낭비하는 것입니다.