реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> WinAVR - как оно?, Эффективность компилятора
SpiritDance
сообщение May 27 2006, 15:14
Сообщение #16


Дух погибшего транзистора
****

Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288



А собственнно в чем вопрос у автора, если альтернативы gcc как многгоплатформенному компилятору особой нет? Знаю что компилятор реально хороший, под AVR проигрывает только IAR. Но есть некоторые мелкие особенности использования gcc в целом:
1 некоторые версии могут быть глючными даже при том что получили стабильный номер.
2 старшие версии могут в некоторых моментах быть не совместимыми с предыдущими, причем это как правило не документируется, так как создатели такие моменты просто могут упустить из вида.
3 существует обилие документации но вся она бестолковая, создается впечатление вороха бумажек вместо прошитых и разложенных по папкам документов
4 своеобразный синтаксис асм, берущий начало от AT&T, хотя многим нравится, я лично тоже не против.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
klen
сообщение May 27 2006, 17:29
Сообщение #17


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Вставлю вой пятачек с двумя дырачкамиsmile.gif

как выразились многие коллеги выше - компиллер это ИНСТУМЕНТ!, поэтому его надо выбирать исходя из постоновки задачи, и я сними глубоко уважаемо согласен. Это Раз. С другой стороны человек не конечнй автомат с известным числом состояний, поэтому компиллер (то есть друга) нада выбирать по любви и убеждению, чтобы "вместе прошивку делать", раскрыть так сказать потенциал!! Это как минимум два.
Я привел довольно общие два критерия выбора. На самом деле их мильон!!! Лично для меня вопрос заданный автором аналогичен вопросу "А тебе какие нравятся больше,черненькие или светленткие? Мне? Мне больше нравятся полненькие!!"

Философская тема однако smile.gif
Go to the top of the page
 
+Quote Post
aesok
сообщение May 27 2006, 18:33
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(msn @ May 27 2006, 02:10) *
.... до сих пор нет нормально реализованной printf, ...


Что вам не хватает в 'printf', можно подробнее?
Go to the top of the page
 
+Quote Post
msn
сообщение May 28 2006, 22:18
Сообщение #19


Частый гость
**

Группа: Свой
Сообщений: 126
Регистрация: 1-01-06
Из: Украина, Киев
Пользователь №: 12 759



Цитата([banned] @ May 27 2006, 09:21) *
Цитата(msn @ May 27 2006, 03:10) *

Пользуюсь больше 4-х лет.

до сих пор нет нормально реализованной printf


ну если ОНА так нужна то можно было уж свою написать и поделится с общественностью !

В большинстве случаев так и есть использую, свои функции из разряда print_num, print_hex, print _str, print _pstr и т.д. Но когда переносишь часть кодов, например, с какого ни будь 8051 для которого обычно пишу в Keil (там printf на мой взгляд очень хорошо сделано) то довольно таки накладно менять. Еще printf очень удобно пользоваться софте содержащим очень много разнородных сообщений для работы с пользователем, у меня это промышленные контролеры, где по объему эти сообщения / меню / разнообразная информация и т.д. занимают, чуть ли не половину места программы.
Свою не писал, не вижу смысла, использую уже написанные до меня (в инете их превеликое множество), допустим из Procyon AVRlib.


Цитата(aesok @ May 27 2006, 21:33) *
Цитата(msn @ May 27 2006, 02:10) *

.... до сих пор нет нормально реализованной printf, ...


Что вам не хватает в 'printf', можно подробнее?

Во первых первое что попадается на глаза при прочтении мануала Standard IO facilities:
Warning:
This implementation of the standard IO facilities is new to avr-libc. It is not yet expected to remain stable, so some aspects of the API might change in a future release.
Уже настораживает.

Когда то писал софт на 8515 (простенький диспетчерский контролер, задачей которого было прослушивание линии вывод разных сообщений и в нагрузку управлении нескольким дискретными входами / выходами), так вот из 8 КБ код и вызовы printf сожрали почти 6,5 КБ, т.е. больше 80 %. Частично посмотрел в дебугере реализацию самой функции и ее вызовом особенно где было несколько параметров (в основном целы числа, строки и символы) сложилось такое впечатление что ни кто ни чего не оптимизировал.
Go to the top of the page
 
+Quote Post
_4afc_
сообщение May 29 2006, 12:54
Сообщение #20


Профессионал
*****

Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



Я тоже пользуюсь только им, но раньше ( а скорее всего и сейчас) у него была одна особенность - он хранил все данные в RAM перенося их туда из FLASH в начальном коде. Раньше можно было только строки (char) хранить во FLASH. Причём в принципе заставить хранить там данные можно, а вот заставить взять средствами си - не получалось, он не использовал код LPM и брал соответственно значение из RAM.

При изменении переменных из прерываний не забывайте про volatile.

Ну и вообще прерывания лучше на ассемблере писать, а то слишком много ресурсов съедает.

(Пример - обработка внешнего последовательного АЦП на си потребовала бы поставить Atmega48 на 80МГц, периписав код на асм с разделением регистров - уложился в 10 wink.gif
Go to the top of the page
 
+Quote Post
msn
сообщение May 29 2006, 13:51
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 126
Регистрация: 1-01-06
Из: Украина, Киев
Пользователь №: 12 759



Цитата(_4afc_ @ May 29 2006, 15:54) *
Я тоже пользуюсь только им, но раньше ( а скорее всего и сейчас) у него была одна особенность - он хранил все данные в RAM перенося их туда из FLASH в начальном коде. Раньше можно было только строки (char) хранить во FLASH. Причём в принципе заставить хранить там данные можно, а вот заставить взять средствами си - не получалось, он не использовал код LPM и брал соответственно значение из RAM.

Сейчас вроде все нормально:
Код
prog_char ansi_rus[64]={0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4,    // Таблица перекодировки таблицы ЖКИ в соответствии с таблицей ANSI
...
                        0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7};

...

void print_char(u8_t ch)
{
if (lcd_x>(LCD_COLUMN-1) || lcd_y>(LCD_ROW-1)) {return;}   // Если за пределами ЖКИ
if (ch>=0xc0 && !fl_no_use_ansi_rus) {ch=pgm_read_byte(&ansi_rus[ch-0xc0]);}
lcd_wr_data(ch);                                           // Вывести символ по текущим координатам
lcd_x++;                                                   // Передвигаемся на следующие знакоместо
}


Или

Код
const char txtErrorMaster__0[] PROGMEM = "  Исход. состояние  ";// 0 Текстовое представлениие произошедшей аврии / предупреждения
const char txtErrorMaster__1[] PROGMEM = "   Отказ модуля 1   ";// 1
const char txtErrorMaster__2[] PROGMEM = "   Отказ модуля 2   ";// 2
....

PGM_P txtErorrMaster[] = {txtErrorMaster__0,                    // Буфер для поиндексного доступа
                          txtErrorMaster__1,
                          txtErrorMaster__2,
....
};

....


void print_str(PGM_P addr)
{
u8_t ch;
while ((ch=pgm_read_byte(addr++))) {print_char(ch);}
}
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение May 29 2006, 13:52
Сообщение #22


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
Причём в принципе заставить хранить там данные можно, а вот заставить взять средствами си - не получалось, он не использовал код LPM и брал соответственно значение из RAM.


Да, к сожалению, невозможность легко манипулировать данными из флэш
было и остается самым серьезным недостатком avr-gcc.
Здесь ИАР рулит однозначно.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
Postoroniy_V
сообщение May 29 2006, 13:54
Сообщение #23


МедвеД Инженер I
****

Группа: Свой
Сообщений: 816
Регистрация: 21-10-04
Пользователь №: 951



Цитата(msn @ May 29 2006, 02:18) *
В большинстве случаев так и есть использую, свои функции из разряда print_num, print_hex, print _str, print _pstr и т.д. Но когда переносишь часть кодов, например, с какого ни будь 8051 для которого обычно пишу в Keil (там printf на мой взгляд очень хорошо сделано) то довольно таки накладно менять. Еще printf очень удобно пользоваться софте содержащим очень много разнородных сообщений для работы с пользователем, у меня это промышленные контролеры, где по объему эти сообщения / меню / разнообразная информация и т.д. занимают, чуть ли не половину места программы.
Свою не писал, не вижу смысла, использую уже написанные до меня (в инете их превеликое множество), допустим из Procyon AVRlib.

тоесть вы хотите сказать что в WInAvr не реализованы аналоги ваших -
print_hex,print_num,print _str,print _pstr посредством родного (winavr) PRINTF?
или то что они жрут много?


--------------------
Cogito ergo sum
Go to the top of the page
 
+Quote Post
defunct
сообщение May 29 2006, 14:10
Сообщение #24


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



bb-offtopic.gif

Цитата(_4afc_ @ May 29 2006, 15:54) *
Ну и вообще прерывания лучше на ассемблере писать, а то слишком много ресурсов съедает.

(Пример - обработка внешнего последовательного АЦП на си потребовала бы поставить Atmega48 на 80МГц, периписав код на асм с разделением регистров - уложился в 10 wink.gif

Не убедительно ;>
В таком случае лучше вообще все писать на асм..

Не вижу смысла писать на Си под чипы у которых меньше 16k Flash..
Не исключено, что программа которая у Вас выполняется на m48, будучи полностью переписана на asm (и с условием наличия требуемых пинов) с успехом разместилась бы в t13.

ps: Пример - IP стек на ассемблере, чудно влез в m48 вместе с программой решающей прикладную задачу и пакетным драйвером PHY/MAC контроллера, еще 2kb флеша осталось (при этом на 20Mhz помимо выполнения основной задачи и общения с сервером по TCP обеспечивается еще и стабильный отклик 1ms на несколько десятков потоков ping'a с пакетами (ICMP) по 256 байт). Для решения этой же задачи на Си потребовался бы ARM ;>
Go to the top of the page
 
+Quote Post
aesok
сообщение May 29 2006, 14:27
Сообщение #25


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(msn @ May 29 2006, 01:18) *
Во первых первое что попадается на глаза при прочтении мануала Standard IO facilities:
Warning:
This implementation of the standard IO facilities is new to avr-libc. It is not yet expected to remain stable, so some aspects of the API might change in a future release.
Уже настораживает.


printf - Это стандартная функция и она не будет изменяться.

Что касается функций открытия/закрытия потоков, то эти изменения уже произошли в avr-libc версии 1.4. В версии 1.2 была функция 'fdevopen' которая использовала динамическое выделение памяти (malloc()), в версии 1.4 этой функции нет.

Цитата(msn @ May 29 2006, 01:18) *
Когда то писал софт на 8515 (простенький диспетчерский контролер, задачей которого было прослушивание линии вывод разных сообщений и в нагрузку управлении нескольким дискретными входами / выходами), так вот из 8 КБ код и вызовы printf сожрали почти 6,5 КБ, т.е. больше 80 %.


Скорее всего это произошло из за того, что вы использовали полную версию 'printf' с поддержкой чисел с плавающей точкой. О разных вариантах функции 'printf', а точнее 'vfprintf', посмотрите описание 'vfprintf'. Если вам не нужны числа с плавающей точкой используйте стандартную версию функции 'vfprintf'.

Код
#include <stdio.h>

int
uart_putchar(char c, FILE *stream)
{
    return 0;
}


FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

int main()
{      
    stdout = &uart_str;
    printf("test");
    
    return 0;

}


Размер кода для этой программы при использовании стандартной версии 'vfprintf' равен примерно 1.8KB, при использовании полной версии (с плавающей точкой) примерно 4,5KB. Конечно не бесплатно .....


Цитата(msn @ May 29 2006, 01:18) *
Частично посмотрел в дебугере реализацию самой функции и ее вызовом особенно где было несколько параметров (в основном целы числа, строки и символы) сложилось такое впечатление что ни кто ни чего не оптимизировал.


'vfprintf' написанна на С, пока не нашлось героя переписать ее на асме. smile.gif

Анатолий.

Сообщение отредактировал aesok - May 29 2006, 14:33
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение May 29 2006, 14:42
Сообщение #26


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
Скорее всего это произошло из за того, что вы использовали полную версию 'printf' с поддержкой чисел с плавающей точкой.

BTW в makefile который генерирует mfile присутствуют специальные опциии линкера для printf и scanf *_LIB_MIN и *_LIB_FLOAT.

Цитата
'vfprintf' написанна на С, пока не нашлось героя переписать ее на асме. smile.gif

А никто не пробовал играться с С++ и его перегружаемыми cin/cout?


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
sff
сообщение May 29 2006, 15:22
Сообщение #27


Частый гость
**

Группа: Свой
Сообщений: 172
Регистрация: 23-04-06
Пользователь №: 16 404



Я WinAVR использую года 2 и за это время сложилось достаточно положительное впечатление, но не без причуд. Похоже на уровне оптимизации WinAVR "не знает" что регистры 8 разрядные (разработчики портировали с другой архитектуры без существенной переработки, это моё личное мнение)

Например возьмём убогий пример, и откоипилируем с опцией -O2, компилятор последний офиц WinAVR (а по сути здесь и не важно)
Код
uint8_t get_small_val()
{
    return 0x8;
}
uint32_t test(uint32_t val)
{
    uint8_t tmp = get_small_val();
    val += (uint16_t)tmp << 8;
    return val;
}


то получим
Код
00000284 <get_small_val>:
     284:    88 e0           ldi    r24, 0x08; 8
     286:    90 e0           ldi    r25, 0x00; 0
     288:    08 95           ret

0000028a <test>:
     28a:    ef 92           push    r14
     28c:    ff 92           push    r15
     28e:    0f 93           push    r16
     290:    1f 93           push    r17
     292:    7b 01           movw    r14, r22
     294:    8c 01           movw    r16, r24
     296:    f6 df           rcall    .-20     ; 0x284 <get_small_val>
     298:    99 27           eor    r25, r25
     29a:    98 2f           mov    r25, r24
     29c:    88 27           eor    r24, r24
     29e:    aa 27           eor    r26, r26
     2a0:    bb 27           eor    r27, r27
     2a2:    8e 0d           add    r24, r14
     2a4:    9f 1d           adc    r25, r15
     2a6:    a0 1f           adc    r26, r16
     2a8:    b1 1f           adc    r27, r17
     2aa:    bc 01           movw    r22, r24
     2ac:    cd 01           movw    r24, r26
     2ae:    1f 91           pop    r17
     2b0:    0f 91           pop    r16
     2b2:    ff 90           pop    r15
     2b4:    ef 90           pop    r14
     2b6:    08 95           ret


Во-первых функции которые возвращают uint8_t расширяются до int (строчка 286), причём как я смотрел совершенно не зависит от опций оптимизаций, конечно есть волшеьная опция -mint8 которая заставляет int принимать 8 бит, но при этом разработчики не гарантируют что все проекты откомпилируются с данной опцией.

Во-вторых по согласованию распределения регистров с переменными, есть 3 типа, в стандартном, бедет всегда такая картина при передаче и возврашение 32 битного числа (292-294, 2aa-2ac). Причем если активно использовать 32 битные типы (да понимаю AVR не затачивался под 32) то таких констукций будет много. Причем нам явно младший байт после сдвига tmp прибавлять не надо, это очевидно. Но GCC этого "не прнимает". Причем если не написать (uint16_t) перед опеорацией сдвига, то компилятор расширит uint8_t до int, а int знаковое, и после сдвига явно сбросит 7 бит, чтобы расширение произошло "корректно".

Есть ещё моного тонкостей на которые я наткнулся...
Но вот если в проекте на так много 32битных вычисление то GCC может очень изащренно оптимизировать код, бывало когда я смотрел дамп аж сам биву давался как он налавкачел.. =)

Ещё один огромнейший и неоспоримый плюс GCC это ассемблерные вставки. В них можно написать что-то типа макроса и компилятор будет сам выбирать какие регистры ему в конкретном случае лучше использовать (применительно к inline конструкциям)

Код
    __asm__ __volatile__ (    
        "ldd %0, Z+14"            "\r\n"
        "andi %0, 0x8C"            "\r\n"
        "lsr %0"                "\r\n"        
        "mov __tmp_reg__, %0"    "\r\n"
        "lsr %0"                "\r\n"
        "swap __tmp_reg__"        "\r\n"
        "or %0, __tmp_reg__"    "\r\n"        
    : "=r" (resp)
    : "z" (data)
    );

Вместо %0, в котором размещается resp, компилятор сам подставит необхолимые регистр, далее указываем компилятору чтобы в Z было data. Если бы в констукции использовался явно какой-то регистр (например после mul) то его нужно было бы включить в список экранируемых регистров ( : "r1" , после : "z" (data) ). При это генерируемы код, если правильно составить макрос булет 100% безопасным.
Тема написания вставок вообще очень интересная, думаю общий обзор дал..

Я использую WinAVR на всех проектах с AVR, а где код сильно тормозил, использовую вставочку =)
Go to the top of the page
 
+Quote Post
msn
сообщение May 29 2006, 17:05
Сообщение #28


Частый гость
**

Группа: Свой
Сообщений: 126
Регистрация: 1-01-06
Из: Украина, Киев
Пользователь №: 12 759



Цитата(Postoroniy_V @ May 29 2006, 16:54) *
тоесть вы хотите сказать что в WInAvr не реализованы аналоги ваших -
print_hex,print_num,print _str,print _pstr посредством родного (winavr) PRINTF?
или то что они жрут много?

Много жрут.

Цитата(aesok @ May 29 2006, 17:27) *
Скорее всего это произошло из за того, что вы использовали полную версию 'printf' с поддержкой чисел с плавающей точкой. О разных вариантах функции 'printf', а точнее 'vfprintf', посмотрите описание 'vfprintf'. Если вам не нужны числа с плавающей точкой используйте стандартную версию функции 'vfprintf'.

Так и есть мне нужно было просчитывать несколько значений вытянутых из линии, результатом были числа с плавающей точкой (нужно было квадратный корень вычислять и выводить результат с точностью до 3 знаков после запятой). Все написал в лоб, без оптимизации.
Go to the top of the page
 
+Quote Post
pitt
сообщение Jun 2 2006, 00:22
Сообщение #29


Местный
***

Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672



"Но вот для AVR (иногда надо делать "контроллеры светодиодов" за 1.5$)"
Если время разработки дорого, а проект достатчно маленький и не сильно сложный CVAVR за 150 евро самое как раз. А вообще, если программирует электрик, то лучшего выбора не будет. Для профессионального программера - WINAVR очевидно лучше.


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 00:51
Сообщение #30


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Неужто лучше ImageCraft ?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 13:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01523 секунд с 7
ELECTRONIX ©2004-2016