ilichev 0 2 сентября, 2011 Опубликовано 2 сентября, 2011 (изменено) · Жалоба Добрый день всем, Пять рабочих дней занимался переводом проекта с CV на IAR, далее привожу подробный отчет, на что стоит обратить внимание. Может кому пригодится. Всё по горячим следам, пока не забыл. Имеем: проект на CV2.03.9, чип ATmega64A. Еще бутлоадер на том же CV, размер 8192 байт. Цель: перевести проект на IAR5.30 с минимальным изменением кода. Причины: а) нехватка памяти flash для развития проекта, б) потребность использовать С++ и float64. Бутлоадер переводить не будем, т.к. нет необходимости. Использую EWAVR_CompilerReference.pdf, отличная документация. 1. Создал пустой проект в IAR, указал чип, Memory model = small, Library = DLIB, DSTACK = 512 байт, CSTACK = 128 уровней (256 байт). 2. Опции компилятора: Extra options: добавил command line options: --string_literals_in_flash --root_variables Первая - чтобы строки размещались во flash. Вторая - чтобы все статические переменные в SRAM и особенно EEPROM были размещены в памяти, даже если они не используются. 3. Опции линкера: Extra options: добавил command line options: -Ointel-standard,(CODE)=.hex -Ointel-standard,(XDATA)=.eep Эти команды нужны для формирования привычных файлов HEX и EEP, как в CodeVision и AVRStudio. Остальные настройки проекта - по вкусу. 4. Где нужно - инклудятся <ioavr.h> и <intrinsics.h>. 5. Переделываются все прерывания на следующий шаблон: #pragma vector = TIMER0_COMP_vect __interrupt void TIMER0_COMP_isr(void) { //... } 6. Все переменные bit заменил на bool. 7. Все объявления указателей на строку во flash заменил на такого типа: const unsigned char __flash *ResetSourceText; Во все объявления переменных в EEPROM добавил __eeprom, и для констант во flash добавил __flash. 8. Разрешения и запрещения прерываний заменил на __enable_interrupt() и __disable_interrupt(), сбросы сторожевого таймера на __watchdog_reset(). 9. Все бинарные константы типа 0b01100011 заменил на BINARY(01100011). Макрос взял здесь. 10. Все ассемблерные вставки заменил на asm("..."). Перенос строки внутри вставки был '\', теперь '\n'. Пример: asm("cli \n jmp 0"); 11. Функция sprintf() в IAR не поддерживает форматную строку из flash. Для этого инклудим <pgmspace.h> и используем функцию sprintf_P(). То же с функцией strcpyf() -> strcpy_P(). 12. Функция sprintf_P() не поддерживает спецификатор '%p' для строк из flash. Модифицировал библиотечный файл frmwri_p.c. Подробнее см. здесь. 13. Где-то использовалась функция toint() из библиотеки CodeVision. Заменил на: //interprets c as a hexadecimal digit and returns an usigned char from 0 to 15. inline unsigned char toint(char c) { if ((c>='0')&&(c<='9')) return (c-'0'); else if ((c>='a')&&(c<='f')) return (c-'a')+10; else if ((c>='A')&&(c<='F')) return (c-'A')+10; else return 0; } 14. Использовал библиотеку софтварной реализации I2C из CodeVision. Поискал готовую для IAR, прикрутил avrlib, не работает, запустить не удалось. Написал свою библиотеку под замену вызовов i2c_start(), i2c_stop(), i2c_write(), i2c_read(), отладил, работает. 15. Проверяю в работе. Периодически сбрасывается по WDT. Долго копался, выяснил, что CV при доступе к переменным EEPROM на чтение и на запись запрещает прерывания, а IAR запрещает только на запись. Нашел решение здесь. Сравнил eeprom.s90 по ссылке и тот, который есть в IAR. Изменения заключаются в том, что при чтении и записи прерывания запрещаются, а затем восстанавливаются, можно смело использовать и в прерываниях, и в основном потоке. Добавил измененный файл в проект, далее выполнил действия по списку - см. EWAVR_CompilerReference.pdf, Overriding library modules using IAR Embedded Workbench. Еще для компиляции понадобилось скопировать в папку проекта файл macros.m90. 16. При тестировании с бутлоадером обнаружил, что в проекте бутлоадера CodeVision сам переключает таблицу прерываний на начало бутлоадера. А в проекте application - на начало flash. IAR такого не делает. Поэтому при выходе из бутлоадера мы оказались в application, но с таблицей прерываний в области бутлоадера. Короче, это решилось добавлением переключения таблицы прерываний на начало flash перед первым разрешением прерываний: MCUCR = 1; MCUCR = 0; __enable_interrupt(); 17. Еще обнаружил, что переход на бутлоадер jmp 0x7000 уходит куда-то не туда. Выяснилось, что ассемблер у IAR отличается от атмеловского и в jmp принимает адрес в байтах, а не в словах. То есть надо задавать удвоенный адрес. Итог: для перехода по адресу 0x7000 выполняем код: asm("cli \n jmp 0xE000"); Вроде бы пока всё, если еще что-то вылезет - допишу. Приглашаю всех, у кого есть опыт переноса проекта с CodeVision на IAR, описывать симптомы проблемы и решение здесь. Изменено 3 сентября, 2011 пользователем Konstantin Ilichev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khlenar 5 2 сентября, 2011 Опубликовано 2 сентября, 2011 · Жалоба С AVR мало работал, проекты которые делал, делал на CV. Хотел спросить, как ощущения после перевода, по оптимизации, скорости ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 2 сентября, 2011 Опубликовано 2 сентября, 2011 · Жалоба Присоединяюсь к коллеге.Приведите,пожалуйста,цифры по расходу флэш и ОЗУ для обоих компиляторов. Если есть критические места по скорости так-же было-бы интересно сравнение в тактах/микросекундах. З.Ы. Плюсами,как я понял в проекте на яре не пахнет и нехватка флэш - главная причина? ИМХО, в таком случае овчинка не стоит выделки и переход на 128 кристалл представляется более быстрым и дешевым вариантом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ilichev 0 2 сентября, 2011 Опубликовано 2 сентября, 2011 (изменено) · Жалоба Приведите, пожалуйста, цифры по расходу флэш и ОЗУ для обоих компиляторов. Привожу: 1. Проект на CodeVisionAVR 2.03.9: Memory model: Small Optimize for: Size Optimization Level: Maximal (s)printf features: long, width, precision (без поддержки float) Bit Variables Size: 64 вроде больше ничего не влияет. Результат компиляции: Program size: 56052 bytes 2. Проект на IAR 5.30: Memory model: Small Library: Normal DLIB Printf formatter: Small (без поддержки float) Language: Embedded C++ Optimizations: Size, Medium (Common subexpression elimination, Code motion, Clustering of variables), без Cross-call'ов. Command line options: --string_literals_in_flash остальное вроде тоже не влияет. В файле frmwri_p.c сделал другой дефайн, чтобы уравнять условия сравнения: #define NO_FLOATS. Результат компиляции: 56271 bytes of CODE memory (+8 range fill) Далее меняю настройку оптимизации: Optimizations: Size, High (Maximum optimization) (Common subexpression elimination, Function inlining, Code motion, Clustering of variables, Type-based alias analysis), без Cross-call'ов. Результат компиляции: 53645 bytes of CODE memory (+8 range fill) Еще раз меняю настройку оптимизации: Optimizations: Size, High (Maximum optimization) (Common subexpression elimination, Function inlining, Code motion, Cross call, Clustering of variables, Type-based alias analysis), Number of cross-call passes: 2. Результат компиляции: 43119 bytes of CODE memory (+8 range fill) Теперь попробуем оптимизацию по скорости: Optimizations: Speed, Medium (Common subexpression elimination, Code motion, Clustering of variables), без Cross-call'ов. Результат компиляции: 56271 bytes of CODE memory (+8 range fill) Теперь такая конфигурация: Optimizations: Speed, High (Maximum optimization) (Common subexpression elimination, Function inlining, Code motion, Cross call, Clustering of variables, Type-based alias analysis), Number of cross-call passes: 2. Результат компиляции: 55309 bytes of CODE memory (+8 range fill) Вывод очевиден: результат IAR компактнее. Расход ОЗУ сравнить невозможно, так как в CodeVision задается только DSTACK, а под CSTACK отдается весь остаток памяти. В IAR же DSTACK и CSTACK задаются явно. Куча не используется, поэтому можно считать, что расход ОЗУ одинаковый или примерно одинаковый. Upd: Вообще, я же заменил переменные bit на bool, поэтому минимум на 64 байта ОЗУ расходуется больше в IAR (если я правильно полагаю, что на один bool расходуется один байт ОЗУ). Быстродействие в этом проекте трудно оценить, поскольку параллельно выполняются несколько алгоритмических механизмов, нет задач, которые можно "измерить". Могу сказать только субъективно и визуально: для всех шести компиляций разницы не заметил. Данные принимаются, обрабатываются, сохраняются, передаются, часы идут, частоты измеряются. Всё как обычно. Если есть критические места по скорости так-же было-бы интересно сравнение в тактах/микросекундах. Обработка в прерываниях судя по ассемблерному листингу достаточно эффективна, есть некоторые лишние команды, но не более, чем в CodeVision. Измерять в тактах не хочется. Самые важные места у меня сделаны на ассемблере, там без замечаний. Плюсами, как я понял в проекте на яре не пахнет и нехватка флэш - главная причина? Главный плюс - возможность писать на С++, использовать классы и другие удобства языка. Второй плюс - код компактнее. Третий плюс - IDE поудобнее будет (только цвет фона пользовательский нельзя установить), чем в CV, хотя в CV есть свои полезные штучки. ИМХО, в таком случае овчинка не стоит выделки и переход на 128 кристалл представляется более быстрым и дешевым вариантом. Если учесть, что уже продано значительное количество устройств, то этот вариант отпадает: мы можем только обновить прошивку, никаких аппаратных изменений. Да и надо развиваться, в конце концов, осваивать легендарный IAR. Изменено 3 сентября, 2011 пользователем Konstantin Ilichev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 3 сентября, 2011 Опубликовано 3 сентября, 2011 · Жалоба Спасибо за ваши данные,очень убедительно.Получается, iar с оптимизацией по скорости выиграл по расходу флэша у СV с оптимизацией по размеру. Я тоже недавно перешел на яр, но вот так проекты переводить не пробовал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ilichev 0 3 сентября, 2011 Опубликовано 3 сентября, 2011 · Жалоба Спасибо за ваши данные,очень убедительно. Я тоже недавно перешел на яр, но вот так проекты переводить не пробовал. Дык не за что, было бы полезно кому-то - этого достаточно! По этим шагам даже увесистый проект можно перевести всего за один рабочий день вместе с тестированием. Интересно, а можно в IAR как-то увидеть количество строк в проекте? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться