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

А никаких модулей защиты памяти и прочей байды случаем не включено?

 

Еще может обращение к какой-то периферии которая еще не вышла на режим, добавляете строку дольше где-то висите обращаетесь позже, убираете строку, обращаетесь раньше?

 

 

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


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

...в смысле изменялся асм на выходе компилятора? Ты имеешь в виду машинный код? Или прошедший оптимизацию входной асм?

 

после отработки компилятора на выходе получаем файлы с коментнутыми текстовыми инструкциями и машинный код

вот там видно пропадание нескольких команд. причём параметры среды одни и те-жи. исходник менялся незначительно - ну типа нопов дополнительных

и уже эффект проявлялся. Никакой оптимизацией это не объяснить. Чистый глюкало компилятора.

Да, и ощущение что именно от больших размеров компилируемой программы зависит. Т.е. это один раз всего было явно поймано за руку.

Кода в то время писал разное(под 51) на мелких замечено не было. только в одном проекте такое проявилось. Сначала как баг, который я не мог

понять природу. Далее методом контрольных точек было найден логический блок, ну и при дальнейшем скурпулёзном просмотре кода выявило

конкретное место и отсутствие команд. после научного метода тыка повлиять на ситуацию - была найдена закономерность.

 

где то так. давно было дело...

 

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


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

Добрый день!

Не стал создавать новую тему.

Вопрос по уровням оптимизации в Keil 5.14.

 

Предыстория такая.

Скачал библиотеку USB с сайта st.com (STSW-STM32092 STM32F0x2xx USB FS device library (UM1717)).

Запустил проект виртуального ком порта.

Убрал из кода файлы отладочной платы, поменял камень на STM32F042K6. Убрал USART. Сделал так, чтобы все что принимается с USB выплёвывалось туда же.

Все работает отлично, определятся на компе, как вирт ком порт, шлю данные из терминала и получаю их же.

В проекте стоит уровень оптимизации 3 (Level 3 (-O3)) по умолчанию.

Если выставить уровень оптимизации 0 (Level 0 (-O0)), то при попытке отправить данные из консоли в контроллер, сваливается в hardfault на 8-й строчке.

При всех других уровнях оптимизации все работает (Level 1 (-O1), Level 2 (-O2)).

 

void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
  uint32_t n = (wNBytes + 1) >> 1;
  uint32_t i;
  uint16_t *pdwVal;
  pdwVal = (uint16_t *)(wPMABufAddr + PMAAddr);
  for (i = n; i != 0; i--)
  {
    *(uint16_t*)pbUsrBuf++ = *pdwVal++; // Тут падает
    pbUsrBuf++;
  }
}

 

Я бы всё понял, если бы было всё наоборот.

Как мне кажется, все указатели и массивы нормально объявлены, в противном случае падало бы на всех уровнях оптимизации.

 

Может есть нормальное описание уровней оптимизации keil'а? Или мысли по этому поводу? Или может быть, кто-нибудь сможет объяснить "на пальцах" как работает оптимизация в keil?

 

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


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

Может есть нормальное описание уровней оптимизации keil'а?

Какой смысл разбираться в деталях оптимизации? Тут ведь как: либо а) в коде ошибка, либо б) баг в компиляторе. Совершенно очевидно, что вариант а) в 100500 раз вероятнее.

 

Или мысли по этому поводу?

Мысли есть, конечно. Заняться старой доброй отладкой. Вытащить из регистров причину Hard Fault. Ну и разбираться дальше.

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


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

Я не раз нарывался на проблеммы с оптимизатором в кейле. много всего было всего не упомниш. вот один пример: есть массив глобальный волятивный. Делаем какие то действия с массивом. После этого разрешаем прерывание и ждём флага окончания изменения данных в массиве. Так вот 1 элемент массива с оптимизатором не менялся. Почему то кейл заганял его в регистр и после обновления массива в прерывании, 1 элемент брал из этого же регистра. это было в версии 4.2 В версии 4.5 уже это было исправлено. Так же попадались примерчики кейловские, например с USB, которые работали только без оптимизатора.

Так что смотрите ассемблер и поймёте что не так.

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


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

Я считаю, что работоспособность программы при любых уровнях оптимизации и есть тот тест, который отличает хороший код от сами_знаете_какого. У меня тоже бывали случаи, когда не работало при -О3, потом ошибка находилась.

К вопросу в сообщении 18 - возможно, не хватает быстродействия при -О0.

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


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

Я считаю, что работоспособность программы при любых уровнях оптимизации и есть тот тест, который отличает хороший код от сами_знаете_какого.

Именно так. Более того, абсолютно всегда следует с самого начала использовать максимальные уровни оптимизации И НИКОГДА НЕ ОТКЛЮЧАТЬ, единственно, что в процессе работы можно, при жесткой необходимости сдвигать оптимизацию по скорости больше к оптимизации по размеру. Да и то, делать это не глобально, а для отдельных обьектов компиляции - каждому свое.

Даже если при работе со сразу реальной оптимизацией наступить, вдруг (уже много много лет для свежих компиляторов не наступал) на непонимание Вами написанного компилятором, то это легче локализовать и скоректировать в процессе написания в момент проявления проблемы и не постфактум.

 

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


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

Я не раз нарывался на проблеммы с оптимизатором в кейле. много всего было всего не упомниш.

Не верю. Один-два раза за годы - может быть. Остальное - байки, просто не разобрался в ситуации.

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


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

Именно так. Более того, абсолютно всегда следует с самого начала использовать максимальные уровни оптимизации И НИКОГДА НЕ ОТКЛЮЧАТЬ, единственно, что в процессе работы можно, при жесткой необходимости сдвигать оптимизацию по скорости больше к оптимизации по размеру. Да и то, делать это не глобально, а для отдельных обьектов компиляции - каждому свое.

Даже если при работе со сразу реальной оптимизацией наступить, вдруг (уже много много лет для свежих компиляторов не наступал) на непонимание Вами написанного компилятором, то это легче локализовать и скоректировать в процессе написания в момент проявления проблемы и не постфактум.

Иногда включаю -O0, чтобы определить, правильно ли понял меня компилятор. :rolleyes: При этом уровне гораздо легче разбираться по ассемблерным командам.

В Кейле задал 2 Target - Debug и Release - с уровнями -O0 и -O3, и когда не работает, легким движением мыши переключаюсь на Debug.

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


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

Иногда включаю -O0, чтобы определить, правильно ли понял меня компилятор. :rolleyes: При этом уровне гораздо легче разбираться по ассемблерным командам.

Начиная с версии 4.8 у gcc появился уровень оптимизации -Og. Код получается всего где-то на 15% больше, чем -Os, при этом в дизассемблере всё понятно. Красота!

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


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

Иногда включаю -O0, чтобы определить, правильно ли понял меня компилятор. :rolleyes:

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

Понял/не понял, это по результату смотрится. И если не понял, то прежде всего надо смотреть Вы сами-то себя поняли, когда писали? Чего уж тут в ассемблерные команды лезть - сишный текст по любому читается легче. Нежели Вы поняли, что хотели и написали, то компиляторы современные тоже поймут.

Debug и Release - с уровнями -O0 и -O3

Кроме этих "готовых рецептов" есть еще масса ключиков.

 

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


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

На выравнивание pdwVal смотрите. Возможно при O0 компилятор не старается сложить всё по выравненным адресам... Налетал так со встроенным memcpy на Cortex-M0+ (хотя у Вас вроде без плюса).

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


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

В том то и дело, товарищи!

Работает на всех уровнях оптимизации, кроме Leavel - 0 (O0).

Я бы даже не сувался на форум, если было бы наоборот.

При Leavel - 3 (O3) неудобно пользоваться "дебагером". Остальными уровнями (Leavel - 1 (O1) и Leavel - 2 (O2)) еще ни разу не пользовался.

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

Пока в голову ничего не пришло, как начать переписывать USB-шный пример, а может быть придется и всю библиотеку.

 

ViKo, RabidRabbit, спасибо, буду смотреть.

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

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


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

Смею предположить, что с включенной оптимизацией компилятор заменяет этот цикл на memcpy(), которая, в отличие от этого кода, корректно работает с невыровненными данными. При отключенной оптимизации, в зависимости от расположения pbUsrBuf, этот код может приводить к невыровненному доступу, который ядро M0 не поддерживает. За столько времени можно было эту маленькую функцию пройти в окне дизассемблера на любом уровне оптимизации, найти вызывающую падение ассемблерную команду и понять, откуда у нее берутся неправильные аргументы.

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


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

Спасибо всем за помощь!

 

Действительно, если использовать memcpy, то работает и на 0-м уровне оптимизации.

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


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

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

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

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

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

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

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

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

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

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