WinAvr в вопросах и ответах
Alex_NEMO писал(а):...
Вопрос: как мне обратиться к любому элменту массива по индексу а не по содержимому? Через "CASE" сопоставлять содержимое индексу?
Что-то странный у Вас вопрос если есть индекс i то к i-тому элементу обратиться просто vol_tda[i], хотите прочитать элемент массива в переменную x = vol_tda[i]; если наоборот хотите записать переменную в элемент массива то vol_tda[i] = x;
Как-то так.
Парни, спасибо за ответы, я просто "чайник" и некоторые моменты пока ещё не догоняю! Можно ещё спросить, применительно к "статейному" проекту? А то "родная" тема в Статьях, похоже надолго затихла! Правлю "под себя" проект "MINI-16" http://radiokot.ru/circuit/audio/amplifier/34/, хочу реализовать "плавное"(но, в тоже время, быстое) повышение/понижение громкости при входе/выходе в/из режимы "StandBy" и "Mute". В "оригинале" присутствуют в эти моменты очччень неприятные щелчки звука! Потому хочу добавить пару процедур для плавного уменьшения звука от "текущего" до "минимума" и для плавного увеличения звука от "минимума" до "текущего". С vol_min - понятно, это tda_vol[0]. А как определить tda_curr(текущая)? Текущее значение громкости сохраняется в EEPROM и читается оттуда же в переменную p_tda[VOLUME_MENU]. Вернее, диапазон паременной p_tda[VOLUME_MENU] от 0 до 63, а массив "громкостей" всего 32 ??? Как это скрестить? Чего-то я вообще не могу понять.... Или просто тупо: tda_curr = (p_tda[VOLUME_MENU])/2?
- CHYVAK[EASTSIDE]
- Встал на лапы
- Сообщения: 110
- Зарегистрирован: Чт мар 06, 2008 19:23:38
- Откуда: Уфа
Подскажите пожалуйста чем отличаются оптимизации и что каждая делает в WINAVR
0
1
2
3
s
???
Объясните, что делает каждый уровень? пожалуйста
Просто говорят в IAR при каком то уровне оптимизации удаляются бесполезные циклы, у меня некторые прои себя ведут не адекватно, вот поэтому думаю не удалет ли у меня некторые циклы компилятор
0
1
2
3
s
???
Объясните, что делает каждый уровень? пожалуйста
Просто говорят в IAR при каком то уровне оптимизации удаляются бесполезные циклы, у меня некторые прои себя ведут не адекватно, вот поэтому думаю не удалет ли у меня некторые циклы компилятор
- neonix
- Электрический кот
- Сообщения: 1040
- Зарегистрирован: Чт фев 19, 2009 17:46:34
- Контактная информация:
Кратко тут явно не объяснить по ключам GCC целые книги есть
1) -Os (size) - оптимизация по размеру наиболее оптимальная оптимизация по размеру и скорости кода
2) -O0 фактически полное отсутствие оптимизации, глюков на этом уровне не оберешся, к использованию категорически не рекомендуется.
3) -O1 первый уровень оптимизации недалеко ушел от нулевого
4) -O2 второй уровень оптимизации, должен по логике вещей делать код более быстрым но на AVR его только разносит в размерах и в итоге все работает еще медленнее...
5) -O3 фактически тоже самое что и второй
PS: Для AVR советую всегда оставлять оптимизацию по размеру, такой код и работает шустро и мало весит. И не будет таких тупых глюков, как при отсутствие оптимизации, когда прога будет валиться от простейших вычислений. Более конкретно ищите в гугле, ибо щас и не вспомню какие различия в настройках компилятора для разных оптимизаций.
Или изучайте сами
1) -Os (size) - оптимизация по размеру наиболее оптимальная оптимизация по размеру и скорости кода
2) -O0 фактически полное отсутствие оптимизации, глюков на этом уровне не оберешся, к использованию категорически не рекомендуется.
3) -O1 первый уровень оптимизации недалеко ушел от нулевого
4) -O2 второй уровень оптимизации, должен по логике вещей делать код более быстрым но на AVR его только разносит в размерах и в итоге все работает еще медленнее...
5) -O3 фактически тоже самое что и второй
PS: Для AVR советую всегда оставлять оптимизацию по размеру, такой код и работает шустро и мало весит. И не будет таких тупых глюков, как при отсутствие оптимизации, когда прога будет валиться от простейших вычислений. Более конкретно ищите в гугле, ибо щас и не вспомню какие различия в настройках компилятора для разных оптимизаций.
Или изучайте сами
Код: Выделить всё
avr-gcc --help=optimizers
Where technology meets enjoyment.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
сразу хочу сказать, что никаких глюков при отключении оптимизации -O0 быть не может, кроме значительного увеличения объема кода и сильного замедления скорости выполнения (так же программные задержки безбожно врут).
кроме перечисленных "уровней" оптимизации в AVR-GCC имеется еще куча опций, влияющих на оптимизацию, этих опций, наверное, десятка 4. так вот, есть опции, регулирующие способ разбрасывания переменных по регистрам, есть управляющие "разворачиванием" циклов, инлайнингом функций и т.п. Некоторые из этих опций дают увеличение скорости при увеличении объема (разворачивание циклов), другие дают экономию кода при замедлении скорости (например, оформление пролога и эпилога функций в виде отдельных функций). как вы понимаете, разные их комбинации могут давать разные результаты. вот и подобрали 4 комплекта из этой кучи опций, которые автоматически включаются всего единственной опцией -O.
здесь верно говорили, что кроме -Os нет особого смысла использовать прочие варианты: как правило, это наиболее оптимальный вариант и по скорости и по объему. мои эксперименты подтвердили, что цикл, который выполняется за 33148 мкс при компиляции с -Os ускоряется всего до 33106 мкс при опции -O3, зато размер кода увеличивается почти на 18%.
но главное, что вы должны знать: при включенной оптимизации становится очень затруднена отладка пошаговая в студии или протеусе: компилятор так "тасует" код, что порой целые куски кода, который явно полезный, оказываются черт знает где и хрен поймешь, когда исполняется. а вот при выключенной оптимизации каждая строчка исполняется, как положено. поэтому, если у вас неоптимизированная программа влезает в память МК, вы можете отладить логику ее работы при помощи отладчика, а потом включить оптимизацию и собрать компактную и быструю версию.
главное: оптимизатор не портит код! если у вас неоптимизированная и оптимизированная программы работают по-разному (скорость не считается) - это говорит не о глюке оптимизатора, а о том, что вы написали программу безграмотно, с ошибками. только и всего.
кроме перечисленных "уровней" оптимизации в AVR-GCC имеется еще куча опций, влияющих на оптимизацию, этих опций, наверное, десятка 4. так вот, есть опции, регулирующие способ разбрасывания переменных по регистрам, есть управляющие "разворачиванием" циклов, инлайнингом функций и т.п. Некоторые из этих опций дают увеличение скорости при увеличении объема (разворачивание циклов), другие дают экономию кода при замедлении скорости (например, оформление пролога и эпилога функций в виде отдельных функций). как вы понимаете, разные их комбинации могут давать разные результаты. вот и подобрали 4 комплекта из этой кучи опций, которые автоматически включаются всего единственной опцией -O.
здесь верно говорили, что кроме -Os нет особого смысла использовать прочие варианты: как правило, это наиболее оптимальный вариант и по скорости и по объему. мои эксперименты подтвердили, что цикл, который выполняется за 33148 мкс при компиляции с -Os ускоряется всего до 33106 мкс при опции -O3, зато размер кода увеличивается почти на 18%.
но главное, что вы должны знать: при включенной оптимизации становится очень затруднена отладка пошаговая в студии или протеусе: компилятор так "тасует" код, что порой целые куски кода, который явно полезный, оказываются черт знает где и хрен поймешь, когда исполняется. а вот при выключенной оптимизации каждая строчка исполняется, как положено. поэтому, если у вас неоптимизированная программа влезает в память МК, вы можете отладить логику ее работы при помощи отладчика, а потом включить оптимизацию и собрать компактную и быструю версию.
главное: оптимизатор не портит код! если у вас неоптимизированная и оптимизированная программы работают по-разному (скорость не считается) - это говорит не о глюке оптимизатора, а о том, что вы написали программу безграмотно, с ошибками. только и всего.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Danko
- Сверлит текстолит когтями
- Сообщения: 1287
- Зарегистрирован: Пн окт 13, 2008 11:45:54
- Откуда: РФ, Крым, г.Бахчисарай
- Контактная информация:
вопрос к AVR:
версии WinAvr от 2010 года компилируют с большей оптимизацией чем версии от 2007 года?
версии WinAvr от 2010 года компилируют с большей оптимизацией чем версии от 2007 года?
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
я не пользовался версией за 2007 год, самая первая моя версия - конец 2008. По сравнению с 20090313 лично я не заметил существенного выигрыша в 20100110, однако знающие товарищи утверждают, что на каждые 4-5 килобайт кода новая версия дает примерно 100-200 байт экономииDanko писал(а):вопрос к AVR:
версии WinAvr от 2010 года компилируют с большей оптимизацией чем версии от 2007 года?
правда, есть мнение, что в 20100110 присутствует небольшой глюк, который может попортить кровь при работе с прерываниями, если используется атрибут ISR_NOBLOCK - но это экзотика, в общем-то... я пока не страдаю.
в 2010-й версии сильно переделан модуль работы с EEPROM: появились функции обновления данных (т.е. не перезаписывают, если данные не изменились), а так же запись блока данных теперь намного оптимальнее, чем раньше. поэтому при работе с EEPROM выигрыш в размере кода может быть очень заметен.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- AI_Disable
- Сверлит текстолит когтями
- Сообщения: 1116
- Зарегистрирован: Чт окт 15, 2009 14:16:18
- Откуда: Екб
- Контактная информация:
Решил провести для себя небольшой эксперимент: взял 5 первых попавшихся своих проектов и сравнил размеры скомпилированных прошивок на уровне оптимизации Os между WinAVR-20090313 и WinAVR-20100110. В среднем получилось, что последняя версия компилятора делает на 0,52% более компактную прошивку. Ниже приведена сводная таблица. Да, описание прошивки не самое корректное, но обратите внимание на тот факт, что в случаи с мегой32 и кодом ~16кб экономия составила всего 30байт - капля в море при 32кб флэша. Однако в случаи с тини13 и кодом ~1кб экономия составила целых 24 байта! Честно говоря, я даже немного удивился, ведь помню как при написании этой программы я отвоевывал байт за байтом, чтоб уместить всё в 1кб флэша тини13. А тут сбросил столько веса, просто обновив компилятор.


- Вложения
-
- optim.PNG
- (44.43 КБ) 544 скачивания
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
а вы используете "тонкую" оптимизацию?
--param inline-call-cost=X поможет изменить повдение оптимизатора при инлайнинге функций. праметр Х может быть в пределах от 0 до 12, по умолчанию 9. попробуйте подобрать это значение - часто помогает очень заметно.
-fno-split-wide-types поможет вам, если в программе используются рассчеты с числами long или много функций, которые в параметрах имеют типы int или более длинные.
указание для функции main() атрибута OS_main так же даст от 4 до 12 байт экономии, а то и более.
--param inline-call-cost=X поможет изменить повдение оптимизатора при инлайнинге функций. праметр Х может быть в пределах от 0 до 12, по умолчанию 9. попробуйте подобрать это значение - часто помогает очень заметно.
-fno-split-wide-types поможет вам, если в программе используются рассчеты с числами long или много функций, которые в параметрах имеют типы int или более длинные.
указание для функции main() атрибута OS_main так же даст от 4 до 12 байт экономии, а то и более.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- AI_Disable
- Сверлит текстолит когтями
- Сообщения: 1116
- Зарегистрирован: Чт окт 15, 2009 14:16:18
- Откуда: Екб
- Контактная информация:
ARV писал(а):а вы используете "тонкую" оптимизацию?
Нет, увы, знал только об её существовании, до сего момента. Но уже вижу, что это имеет смысл: добавил инлайн функции чтения EEPROM и код на тини13 сократился ещё на 18байт. С остальными пока не разобрался, не покажите как их юзать? Просто уж очень часто бывает, что не хватает 100-200 байт и приходится всяко извращаться.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
да так и использовать - укажите эти опции в командной строке компилятора, и всех делов 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- AI_Disable
- Сверлит текстолит когтями
- Сообщения: 1116
- Зарегистрирован: Чт окт 15, 2009 14:16:18
- Откуда: Екб
- Контактная информация:
Я в студии пишу. В случаи c inline сделал так:
Насколько я понял, компилятор меня понял
А вот как другие пользовать до меня не дошло.
Код: Выделить всё
inline unsigned char EEPROM_read(unsigned char Address)
{
...
}Насколько я понял, компилятор меня понял
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
вы поняли не правильно, хотя и получили положительный эффект. в вашем случае во-первых, практичнее пользоваться встроенными функциями для работы с EEPROM из модуля eeprom.h типа
uint8_t eeprom_read_byte(uint8_t *addr);
void eeprom_write_byte(uint8_t *addr, uint8_t data); и так далее.
во-вторых, для функций, которые требуются только в одном единственном модуле надо указывать префикс static - в вашем случае inline сыграло его роль, но static может помочь больше (может, но может и не помочь).
в-третьих, указанные мною опции следует вводить именно так, как я написал, целиком и без фантазий. вводить их следует в опции компилятора - закладка Custom Options для парамтеров проекта. там их и надо ввести по аналогии к уже имеющимся.
uint8_t eeprom_read_byte(uint8_t *addr);
void eeprom_write_byte(uint8_t *addr, uint8_t data); и так далее.
во-вторых, для функций, которые требуются только в одном единственном модуле надо указывать префикс static - в вашем случае inline сыграло его роль, но static может помочь больше (может, но может и не помочь).
в-третьих, указанные мною опции следует вводить именно так, как я написал, целиком и без фантазий. вводить их следует в опции компилятора - закладка Custom Options для парамтеров проекта. там их и надо ввести по аналогии к уже имеющимся.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- AI_Disable
- Сверлит текстолит когтями
- Сообщения: 1116
- Зарегистрирован: Чт окт 15, 2009 14:16:18
- Откуда: Екб
- Контактная информация:
Здравствуйте форумчане, есть небольшой вопрос. Нужно из флеш памяти вытаскивать слова и отображать их на LCD (HD контроллер).
Я организовал так (куски програмы):
сама запись в память const char *msg_1 PROGMEM="DATA";
вот передача на дисплей:
void lcd_puts_mem(const char *str)
{
while(*str) {lcd_putchar(*str); *str++};
}
суть в том, что если написть:
lcd_puts_mem(pgm_read_word(&msg_1));
программа компилится и в железе работает, но компилятор естественно ругается, что в функцию подставляется не указатель, а число ("making pointer from integer without a cast").
Хочется чтоб все было грамотно, потскажите как это сделать? А то никак не могу найти разумное решение
Я организовал так (куски програмы):
сама запись в память const char *msg_1 PROGMEM="DATA";
вот передача на дисплей:
void lcd_puts_mem(const char *str)
{
while(*str) {lcd_putchar(*str); *str++};
}
суть в том, что если написть:
lcd_puts_mem(pgm_read_word(&msg_1));
программа компилится и в железе работает, но компилятор естественно ругается, что в функцию подставляется не указатель, а число ("making pointer from integer without a cast").
Хочется чтоб все было грамотно, потскажите как это сделать? А то никак не могу найти разумное решение
Не умееш - не берись, но не взявшись не научишся.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Rusja2008, вы немного напутали и сделали совсем не то, что задумали.
const char *msg_1 PROGMEM="DATA"; - это объявление во FLASH указателя на строку, а сама строка при этом остается в ОЗУ
изучите листинг и вы в этом убедитесь.
и далее вы загружаете из FLASH именно указатель, а символы строки берете из ОЗУ - все это очевидно по вашему коду.
на самом деле, если вам надо выводить строки на дисплей без всякой зауми, то надо сделать так:
то есть для занесения строки во FLASH и одновременно получение адреса ее надо использовать макрос PSTR(x);
const char *msg_1 PROGMEM="DATA"; - это объявление во FLASH указателя на строку, а сама строка при этом остается в ОЗУ
и далее вы загружаете из FLASH именно указатель, а символы строки берете из ОЗУ - все это очевидно по вашему коду.
на самом деле, если вам надо выводить строки на дисплей без всякой зауми, то надо сделать так:
Код: Выделить всё
void lcd_puts_P(char *str){
char c = pgm_read_byte(str++);
while(c){
lcd_putchar(c);
с = pgm_read_byte(str++);
}
}
lcd_puts_P(PSTR("Привет!"));
то есть для занесения строки во FLASH и одновременно получение адреса ее надо использовать макрос PSTR(x);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Огромное спасибо ARV, действительно строка сидит в ОЗУ. Наступил на огромные грабли
И хочу уточнить: строчка "lcd_puts_P(PSTR("Привет!"));" как раз считывает по адресу в флеш и загоняет на дисплей, а для того чтоб записать строку в память как правильно записать? (PSTR("слово") или не так). Хочу сразу спросить ато WinAVR стоит дома на компе, а я на работе.
И хочу уточнить: строчка "lcd_puts_P(PSTR("Привет!"));" как раз считывает по адресу в флеш и загоняет на дисплей, а для того чтоб записать строку в память как правильно записать? (PSTR("слово") или не так). Хочу сразу спросить ато WinAVR стоит дома на компе, а я на работе.
Не умееш - не берись, но не взявшись не научишся.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
я не совсем понял, что вам надо.
PSTR("Вася"); поместит строку "Вася" во FLASH. макрос PSTR(x) удобно использовать именно в тех случаях, когда надо просто вывести строку при помощи функции, тогда этот макрос используется именно как указатель на строку во FLASH. если же вам просто захотелось сделать во FLASH строку, то это делается элементарно:
если вы посмотрите, как макрос PSTR() устроен, вы увидите то же самое
PSTR("Вася"); поместит строку "Вася" во FLASH. макрос PSTR(x) удобно использовать именно в тех случаях, когда надо просто вывести строку при помощи функции, тогда этот макрос используется именно как указатель на строку во FLASH. если же вам просто захотелось сделать во FLASH строку, то это делается элементарно:
Код: Выделить всё
PROGMEM char name[] = "Вася";если вы посмотрите, как макрос PSTR() устроен, вы увидите то же самое
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!