Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Чудеса с оптимизацией
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
GreyM
Здравствуйте, уважаемые форумчане.

Хочу поделиться с вами историей, которая лично меня привела в ступор.
С недавних пор я занялся тем, что решил запустить FreeFTOS 7.1.0 на STM32F103.

Ситуация осложнялась тем, что я использовал IAR 6.1, в то время как примеры для этой платы были сделаны для IAR 6.3, и мой 6.1 уже не мог корректно открыть такой проект - при попытке открытия сбрасывались все настройки. Но я не расстроился, и выставил все настройки и зависимости вручную. После чего мой код успешно стал уходить в HardFault на инструкции смены стека при попытке запустить первую задачу:

Код
vPortStartFirstTask
    /* Use the NVIC offset register to locate the stack. */
    ldr r0, =0xE000ED08
    ldr r0, [r0]
    ldr r0, [r0]
    /* Set the msp back to the start of the stack. */
    msr msp, r0
    /* Call SVC to start the first task. */
    cpsie i
    svc 0


Я долго бился головой об стену, искал по разным форумам и вообще делал все, что только мог, но проект так и не заработал. Дело осложнялось тем, что я хотел использовать С++ для пользовательской части кода. В конце концов мне улыбнулась удача: на просторах интернета я нашел сайт, на котором его владелец предлагал готовый шаблон проекта для STM32F103 + FreeRTOS 7.1.0 + StdPeriph с использованием С++ - (Ссылка на шаблон. Автор писал, что всё оттестировано на IAR 6.3. В комментах было множество благодарных отзывов и подтверждений корректности работы. Моя версия ИАРа попрежнему не могла корректно открыть проект, поэтому я вручную настроил ссылки на все библиотеки и... Получил hardfault.

После такой неудачи я был окончательно демотивирован и нашел таки установщик иара 6.3. После этого я опять разархивировал проект, открыл его, запустил и был вознагражден мигающей лампочкой. Моему счастью не было предела. Однако, каково же было моё удивление, когда первая версия шаблона, которую я настраивал руками, скомпилированная обновленным ИАРом опять ушла в hardfault. После этого я стал методично сравнивать настройки проекта. Во второй вкладке я дошел до закладки "Оптимизация", которая в шаблоне была выставлена в medium, а в моём проекте была отключена для упрощения отладки. В новом шаблоне я попробовал отключить оптимизацию и - бинго! Он тоже упал.

После этого я пытался играться с параметрами, но любые вариации, при которых оптимизация была ниже средней, приводили контроллер в hardfault. Мне пришлось смириться, ведь, в конце концов, задача была решена. Однако, мой внутренний мир находится в сметении. Я могу понять, что криво написанный код может переставать работать при включении оптимизации. Но как код может переставать работать при её отключении? Заранее благодарен за ваши варианты ответов на этот вопрос.
Палыч
Цитата(GreyM @ May 21 2012, 19:11) *
Но как код может переставать работать при её отключении? Заранее благодарен за ваши варианты ответов на этот вопрос.

Как предположение: при отключении оптимизации перестает работать спецификатор inline. Для криво написанного кода этого может быть достаточно...
Dog Pawlowa
Цитата(GreyM @ May 21 2012, 18:11) *
Но как код может переставать работать при её отключении?

Элементарно. Начинает работать медленно, и не успевает. Не успевает, например, до следующего прерывания. Грубо говоря, контроллер не выходит из прерывания вообще. inline - верно, но это только часть проблемы.
Несколько моих проектов уже давно работают только на полной оптимизации. В кривости не признаюсь, ибо знал на что шёл.
Зато все понятно написано! sm.gif
GreyM
Спасибо за доходчивые ответы sm.gif
Мне это как то не пришло в голову, ведь код инициализации совсем небольшой, а контроллер достаточно мощный. Но на будущее буду иметь в виду.
IgorKossak
Функции без оптимизации могут потреблять несколько больше стека, чем оптимизированные. Переполнение стека однозначно вызывает сбой программы.
jcxz
Цитата(GreyM @ May 21 2012, 21:11) *
Я долго бился головой об стену, искал по разным форумам и вообще делал все, что только мог, но проект так и не заработал. Дело осложнялось тем, что я хотел использовать С++ для пользовательской части кода. В конце концов мне улыбнулась удача: на просторах интернета я нашел сайт,
...

Не надо биться головой об стену и лазить по форумам где 99% сидят такие же wink.gif
Достаточно прочитать документацию о системе исключений (faults) процессора, написать обработчики исключений и найти точку в программе, которая вызывает исключение, потом проанализировать ассемблерный код до этой точки.
Уйдёт на всё это максимум - день.
Вообще - написание программы должно начинаться с написания грамотной обработки исключений.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.