Глюк WinAVR или какаято особенность?

Тема в разделе "WASM.ELECTRONICS", создана пользователем a9d, 10 мар 2010.

  1. a9d

    a9d New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2006
    Сообщения:
    234
    Адрес:
    Zimbabwe
    Вобщем есть простой исходник.
    Код (Text):
    1. #define F_CPU 1000000UL
    2.  
    3. #include <stdlib.h>
    4. #include <avr/io.h>
    5. #include <string.h>
    6. #include <stdio.h>
    7.  
    8. void uart_9600(void)
    9. {
    10.     #define BAUD 9600
    11.  
    12.     #include <util/setbaud.h>
    13.     UBRRH = UBRRH_VALUE;
    14.     UBRRL = UBRRL_VALUE;
    15.     #if USE_2X
    16.     UCSRA |= (1 << U2X);
    17.     #else
    18.     UCSRA &= ~(1 << U2X);
    19.     #endif
    20.  
    21.     UCSRB|=(1<<RXEN)|(1<<TXEN);
    22. }
    23.  
    24. int uart_putchar(char c, FILE *stream);
    25.  
    26. FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE);
    27.  
    28. int uart_putchar(char c, FILE *stream)
    29. {
    30.  
    31.   if (c == '\n')
    32.     uart_putchar('\r', stream);
    33.   loop_until_bit_is_set(UCSRA, UDRE);
    34.   UDR = c;
    35.   return 0;
    36. }
    37.  
    38. int main(void)
    39. {
    40.   uart_9600();
    41.   stdout = &mystdout;
    42.   while(1)
    43.   {
    44.       printf("Hello World\n");
    45.   }
    46.  
    47.   return 0;
    48. }
    Компилим его:

    Program: 450 bytes (2.7% Full)
    (.text + .data + .bootloader)

    Data: 32 bytes (3.1% Full)
    (.data + .bss + .noinit)

    Далее меняем строчку
    Код (Text):
    1. printf("Hello World\n");
    на
    Код (Text):
    1. printf("Hello World\n ");
    Компилим и:

    Program: 1788 bytes (10.9% Full)
    (.text + .data + .bootloader)

    Data: 34 bytes (3.3% Full)
    (.data + .bss + .noinit)

    Т.е добавили один пробел и получили лишний килобайт. Хотя при отладке этот килобай не наблюдаю. Такое ощущение, что у компилятора от пробела сносит башню.

    Это глюк?

    ЗЫ: Eclipse+WinAVR-20100110
     
  2. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Выложите два собранных исполняемых файла.
     
  3. a9d

    a9d New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2006
    Сообщения:
    234
    Адрес:
    Zimbabwe
    Держи. Только сейчас заметил, что они размером отличаются. Но листинг диз-асма идентичный.
     
  4. a9d

    a9d New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2006
    Сообщения:
    234
    Адрес:
    Zimbabwe
    Мдя printf реализован весьма убого. При попытке вывести данных типа float к прошивке накидывается еще пару Кб.
     
  5. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    a9d
    Это не printf убого реализован, это можно отказаться от поддержки float в пользу парк Кб)
     
  6. a9d

    a9d New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2006
    Сообщения:
    234
    Адрес:
    Zimbabwe
    2Black_mirror: Во ремя отладки я смотрел листинг на асме. Он увеличелся незначительно. Просто какого черта winavr добавляет к прошивке какой то мусор.
     
  7. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    a9d
    Во втором случае он добавляет vfprintf, в первом случае printf на нее не ссылается.
     
  8. a9d

    a9d New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2006
    Сообщения:
    234
    Адрес:
    Zimbabwe
    2KeSqueer: Что то я глубоко сомниваюсь, что функция вывода константы типа float занимает пару Кб. Темболее я наблюдал, пошагово в отладчике за дизассеблированым кодом. Длинных функций нет. Весь код который выполняется занимает отсилы байт 500-600. Спрашивается зачем тогда компилятор добавляет ненужный код который даже не выполняется?
     
  9. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    a9d
    А сколько по вашему мнению должна занимать функция для вывода float? Чтобы она ей можно было указать сколько символов выводить до точки, сколько после, выводить ли порядок, дополнять ли число нулями, выводить ли всегда знак, чтобы правильно выводила всякие плюс/минус бесконечности и "не числа", и еще чтобы все вычисления делала на 8 разрядных регистрах, причём из операций, одним из операндов которых является память, можно использовать только загрузку и сохранение, все остальные операции выполнять только с регистрами. После того как ответите на первый вопрос, сможете предъявить ваш ответ, код то есть?
     
  10. a9d

    a9d New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2006
    Сообщения:
    234
    Адрес:
    Zimbabwe
    Полазил в сети и кое что нарыл.

    1) Функцией printf почти никто не пользуется. Т.к если ей не указывать на конец строки "\n", то компилятор к прошивке прицепит комплект функций по работе со строками.
    Поэтому используют функцию fprintf(&mystdout," Hello "); .

    2) Работу с дробными числами WinAVR оптимизирует хорошо. Но вывод через функцию print(и ее аналогии) происходит через заднее место. Т.к. компилятор к прошивке прицепит комплект функций по работе со строками + функции преобразования.
    Поэтому используют:
    Код (Text):
    1.               char mystr[16];
    2.               char mystr1[16];
    3.               double d=3.14433;
    4.               int j=0;
    5.  
    6.       itoa((int)d,mystr,10);
    7.       j=(d-(int)d)*100;
    8.       itoa(j,mystr1,10);
    9.       fprintf(&mystdout,"%s",mystr);
    10.       fprintf(&mystdout,".");
    11.       fprintf(&mystdout,"%s",mystr1);
    12.       fprintf(&mystdout,"\n");
    В этом случае лишнего багажа не будет.
     
  11. a9d

    a9d New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2006
    Сообщения:
    234
    Адрес:
    Zimbabwe
    Забыл написать. В этом случае размер прошивки(в прошивку добавлены строки из второго пункта) уменьшается до 628 байт(код прошивки приведен выше).
    Если же использовать printf (&mystdout,"%.5f",MyDouble) для вывода переменной типа float, то размер прошивки будет составлять 1938 байт.

    Разница очевидна.
     
  12. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    На самом деле немного. Но обычно компилятор с линкером подгружают сразу пачку подпрограмм или подпрограмма пишется универсально - вот вам и кило.