AVR: неожиданный способ оптимизации

При переходе на новую версию компилятора avr-gcc ( c древней  4.3.5 на  4.7.0 ) размер прошивки внезапно уменьшился почти на 10%.  И если раньше прошивка занимала почти всю доступную программную память — 250Кb, то теперь её размер  230Kb, то есть освободилось почти 20Kb flash памяти.

Но при переходе возникли некоторые сложности, и пришлось вносить небольшие изменения в код.

При компиляции возникала ошибка «error: attempt to use poisoned  SIG_OVERFLOW2″, это связано с использованием устаревших имен при объявлении обработчиков прерываний. Для решения этих ошибок надо было заменить: SIG_OVERFLOW2 на TIMER2_OVF_vectSIG_USART0_RECV на USART0_RX_vect, и т.д.

Так как в проекте использовался флаг компилятора -Werror, то все предупреждения компилятора становились ошибками, и процесс компиляции прекращался. По этому,  компилятор выдавал ошибку, если переменная была проинициализирована, но далее не использовалась  «error: variable  set but not used» .  И это были не ошибки в программе, т.к. иногда что бы сбросить флаги в регистрах их надо прочитать, а само считанное значение не нужно.  Что бы обойти  данную ситуацию добавили опцию компилятора -Wno-unused-but-set-variable

Что бы избавиться от  ошибки  «error: dereferencing type-punned pointer will break strict-aliasing rules»  был добавлен флаг -Wno-strict-aliasing

Далее компилятор ругался на prog_char  —  error: ‘prog_char’ is deprecated, что бы договориться с компилятором использовали флаг -Wno-deprecated-declarations

Потом пошли ошибки:
error: passing argument 1 of ‘fputs_P’ from incompatible pointer type
note: expected ‘const char *’ but argument is of type ‘const int *’
для исправления ситуации был добавлен флаг -D__PROG_TYPES_COMPAT__

Далее надо было дописать const при объявлении констант в PROGMEM, иначе возникала ошибка  error: variable  must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

На этом переход на новый компилятор был завершен.

Запись опубликована в рубрике Микроконтроллеры avr с метками , . Добавьте в закладки постоянную ссылку.

3 комментария: AVR: неожиданный способ оптимизации

  1. Ярослав говорит:

    Спасибо большое за заметки на полях. Столкнулся с проблемой, когда объявляю массив-указатель на строки в памяти как был раньше

    const uint16_t *Day_Pointer [] PROGMEM = { DS3231_Day1,DS3231_Day2,
    DS3231_Day3,DS3231_Day4,
    DS3231_Day5,DS3231_Day6,
    DS3231_Day7};

    Студия выдает ошибку Error 1 variable ‘Day_Pointer’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

    Без звездочки выдает кучу варнингов
    Через дерективу PGM_P то же ошибки …

    Никто с этим не сталкивался ?

  2. Артём Двинин говорит:

    А как у Вас объявлены строки? Странно что uint16_t, или они в unicode?
    А массив, мне кажется, надо задать вот так

    const uint16_t * const Day_Pointer [] PROGMEM = { DS3231_Day1,DS3231_Day2 }

    Первый const относится к типу данных, которые будут в массиве, т.е. в будет массив из элементов типа const uint16_t *.
    Второй const относится уже к массиву Day_Pointer.

  3. Ярослав говорит:

    Артем, огромнейшее человеческое спасибо !
    Вы спасли мою голову и стол !
    Сразу видно, что работает профессионал, а то мне всякие Петросяны на форумах пургу заливали

Добавить комментарий

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>