Большой шестнадцатеричный файл из маленькой программы AVR

Сейчас я учу своего друга программировать микроконтроллеры AVR. Мы написали эту небольшую программу, которая отправляет простой код Морзе.

Проблема в том, что после компиляции с помощью AVR-GCC и WinAVR файл a.out имеет размер почти 30 КБ, а шестнадцатеричный файл - 11 КБ, поэтому он не подходит для флэш-памяти attiny2313.

Командная строка WinAVR: avr-gcc -mmcu=attiny2313 -Os -g main.c

Avr-objcopy: avr-objcopy -O ihex a.out a.hex

Вот код:

#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>

void light_led(int ms)
{
 PORTD |= (1 << 4);
 _delay_ms(ms);
 PORTD &= ~(1 << 4);
 _delay_ms(1000);
}

void send_char(int c)
{
 int i;
 for(i = 1; i < 8+1; i++)
 {
  if(c & i) light_led(1000);
  else light_led(500); 
 }
}

int main(void)
{
 DDRD |= (1 << 4);
 //char text[] = {'t', 'e', 's', 't'};
 int i;
 for(i = 0; i < 1; i++) send_char(100);//text[i]);
 return 0;
}

person jblew    schedule 30.09.2013    source источник
comment
Попробуйте вариант с раздеванием. Подробнее см. здесь.   -  person Dayal rai    schedule 30.09.2013
comment
Способ уменьшить шестнадцатеричный код, если ничего не помогает: отказаться от библиотек и реализовать функции вручную, обрезав их (часто слишком гибкие для этой цели) дополнительные функции. Таким образом, неиспользуемые вещи будут исключены... Конечно, код будет некрасивым.   -  person ppeterka    schedule 30.09.2013
comment
ATtiny2313 имеет 2 КБ программной флэш-памяти, но, поскольку она находится в двоичном формате, точный размер шестнадцатеричного файла нельзя сравнивать напрямую. Для выражения одного байта данных флэш-памяти программы в шестнадцатеричном файле требуется намного больше одного байта. Тем не менее, следуйте совету @Dayalrai и убедитесь, что двоичный файл удален и оптимизирован по размеру.   -  person unwind    schedule 30.09.2013


Ответы (1)


Размер шестнадцатеричного файла вводит в заблуждение. Для представления 16 требуется 43 байта, поэтому размер вашего исполняемого файла на самом деле составляет всего 4 КБ.

Тем не менее, передача параметра функции _delay_ms() действительно усложняет код. Вместо этого я попробовал это, всегда вызывая функцию задержки с константой, а исполняемый файл был меньше 190 байт.

#define F_CPU 8000000L
#include <avr/io.h>
#include <util/delay.h>

void light_led(int longer)
{
 PORTD |= (1 << 4);
 if(longer) _delay_ms(1000);
 else  _delay_ms(500);
 PORTD &= ~(1 << 4);
 _delay_ms(1000);
}

void send_char(int c)
{
 int i;
 for(i = 1; i < 8+1; i++)
 {
  if(c & i) light_led(1);
  else light_led(0); 
 }
}

int main(void)
{
 DDRD |= (1 << 4);
 //char text[] = {'t', 'e', 's', 't'};
 int i;
 for(i = 0; i < 1; i++) send_char(100);//text[i]);
 return 0;
}
person uncleO    schedule 30.09.2013
comment
Чтобы расширить этот ответ, из manual AVR libc. чтобы эти функции работали должным образом, должна быть включена оптимизация компилятора, а время задержки должно быть выражением, которое является известной константой во время компиляции. Если эти требования не выполняются, результирующая задержка будет намного дольше (и в основном непредсказуемой), и приложения [..] будут испытывать серьезное раздувание кода из-за подпрограмм библиотеки с плавающей запятой, связанных с приложением, что, по сути, то, что вы видели в ваш код. - person TRON; 01.10.2013
comment
Я думал, что встраивание light_led решит эту проблему, но оказалось, что я получаю ошибку времени компиляции с avr-gcc 4.7.2 и avr-libc 1.8.0; это из теста, добавленного, чтобы избежать подобных ошибок. - person Yann Vernier; 02.10.2013