Перейти к содержанию
    

Опыт перевода проекта с CodeVisionAVR на IAR5.30

Добрый день всем,

 

Пять рабочих дней занимался переводом проекта с 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, описывать симптомы проблемы и решение здесь.

Изменено пользователем Konstantin Ilichev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С AVR мало работал, проекты которые делал, делал на CV. Хотел спросить, как ощущения после перевода, по оптимизации, скорости ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяюсь к коллеге.Приведите,пожалуйста,цифры по расходу флэш и ОЗУ для обоих компиляторов. Если есть критические места по скорости так-же было-бы интересно сравнение в тактах/микросекундах.

 

З.Ы. Плюсами,как я понял в проекте на яре не пахнет и нехватка флэш - главная причина?

ИМХО, в таком случае овчинка не стоит выделки и переход на 128 кристалл представляется более быстрым и дешевым вариантом.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приведите, пожалуйста, цифры по расходу флэш и ОЗУ для обоих компиляторов.

Привожу:

 

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.

Изменено пользователем Konstantin Ilichev

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ваши данные,очень убедительно.Получается, iar с оптимизацией по скорости выиграл по расходу флэша у СV с оптимизацией по размеру.

Я тоже недавно перешел на яр, но вот так проекты переводить не пробовал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ваши данные,очень убедительно. Я тоже недавно перешел на яр, но вот так проекты переводить не пробовал.

Дык не за что, было бы полезно кому-то - этого достаточно!

 

По этим шагам даже увесистый проект можно перевести всего за один рабочий день вместе с тестированием.

 

Интересно, а можно в IAR как-то увидеть количество строк в проекте?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...