Golikov 0 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба А никаких модулей защиты памяти и прочей байды случаем не включено? Еще может обращение к какой-то периферии которая еще не вышла на режим, добавляете строку дольше где-то висите обращаетесь позже, убираете строку, обращаетесь раньше? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба ...в смысле изменялся асм на выходе компилятора? Ты имеешь в виду машинный код? Или прошедший оптимизацию входной асм? после отработки компилятора на выходе получаем файлы с коментнутыми текстовыми инструкциями и машинный код вот там видно пропадание нескольких команд. причём параметры среды одни и те-жи. исходник менялся незначительно - ну типа нопов дополнительных и уже эффект проявлялся. Никакой оптимизацией это не объяснить. Чистый глюкало компилятора. Да, и ощущение что именно от больших размеров компилируемой программы зависит. Т.е. это один раз всего было явно поймано за руку. Кода в то время писал разное(под 51) на мелких замечено не было. только в одном проекте такое проявилось. Сначала как баг, который я не мог понять природу. Далее методом контрольных точек было найден логический блок, ну и при дальнейшем скурпулёзном просмотре кода выявило конкретное место и отсутствие команд. после научного метода тыка повлиять на ситуацию - была найдена закономерность. где то так. давно было дело... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Booger 0 5 февраля, 2016 Опубликовано 5 февраля, 2016 · Жалоба Добрый день! Не стал создавать новую тему. Вопрос по уровням оптимизации в 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 5 февраля, 2016 Опубликовано 5 февраля, 2016 · Жалоба Может есть нормальное описание уровней оптимизации keil'а? Какой смысл разбираться в деталях оптимизации? Тут ведь как: либо а) в коде ошибка, либо б) баг в компиляторе. Совершенно очевидно, что вариант а) в 100500 раз вероятнее. Или мысли по этому поводу? Мысли есть, конечно. Заняться старой доброй отладкой. Вытащить из регистров причину Hard Fault. Ну и разбираться дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vlad_new 1 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Я не раз нарывался на проблеммы с оптимизатором в кейле. много всего было всего не упомниш. вот один пример: есть массив глобальный волятивный. Делаем какие то действия с массивом. После этого разрешаем прерывание и ждём флага окончания изменения данных в массиве. Так вот 1 элемент массива с оптимизатором не менялся. Почему то кейл заганял его в регистр и после обновления массива в прерывании, 1 элемент брал из этого же регистра. это было в версии 4.2 В версии 4.5 уже это было исправлено. Так же попадались примерчики кейловские, например с USB, которые работали только без оптимизатора. Так что смотрите ассемблер и поймёте что не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Я считаю, что работоспособность программы при любых уровнях оптимизации и есть тот тест, который отличает хороший код от сами_знаете_какого. У меня тоже бывали случаи, когда не работало при -О3, потом ошибка находилась. К вопросу в сообщении 18 - возможно, не хватает быстродействия при -О0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Я считаю, что работоспособность программы при любых уровнях оптимизации и есть тот тест, который отличает хороший код от сами_знаете_какого. Именно так. Более того, абсолютно всегда следует с самого начала использовать максимальные уровни оптимизации И НИКОГДА НЕ ОТКЛЮЧАТЬ, единственно, что в процессе работы можно, при жесткой необходимости сдвигать оптимизацию по скорости больше к оптимизации по размеру. Да и то, делать это не глобально, а для отдельных обьектов компиляции - каждому свое. Даже если при работе со сразу реальной оптимизацией наступить, вдруг (уже много много лет для свежих компиляторов не наступал) на непонимание Вами написанного компилятором, то это легче локализовать и скоректировать в процессе написания в момент проявления проблемы и не постфактум. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Я не раз нарывался на проблеммы с оптимизатором в кейле. много всего было всего не упомниш. Не верю. Один-два раза за годы - может быть. Остальное - байки, просто не разобрался в ситуации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Именно так. Более того, абсолютно всегда следует с самого начала использовать максимальные уровни оптимизации И НИКОГДА НЕ ОТКЛЮЧАТЬ, единственно, что в процессе работы можно, при жесткой необходимости сдвигать оптимизацию по скорости больше к оптимизации по размеру. Да и то, делать это не глобально, а для отдельных обьектов компиляции - каждому свое. Даже если при работе со сразу реальной оптимизацией наступить, вдруг (уже много много лет для свежих компиляторов не наступал) на непонимание Вами написанного компилятором, то это легче локализовать и скоректировать в процессе написания в момент проявления проблемы и не постфактум. Иногда включаю -O0, чтобы определить, правильно ли понял меня компилятор. :rolleyes: При этом уровне гораздо легче разбираться по ассемблерным командам. В Кейле задал 2 Target - Debug и Release - с уровнями -O0 и -O3, и когда не работает, легким движением мыши переключаюсь на Debug. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Иногда включаю -O0, чтобы определить, правильно ли понял меня компилятор. :rolleyes: При этом уровне гораздо легче разбираться по ассемблерным командам. Начиная с версии 4.8 у gcc появился уровень оптимизации -Og. Код получается всего где-то на 15% больше, чем -Os, при этом в дизассемблере всё понятно. Красота! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Иногда включаю -O0, чтобы определить, правильно ли понял меня компилятор. :rolleyes: При этом уровне гораздо легче разбираться по ассемблерным командам. Понял/не понял, это по результату смотрится. И если не понял, то прежде всего надо смотреть Вы сами-то себя поняли, когда писали? Чего уж тут в ассемблерные команды лезть - сишный текст по любому читается легче. Нежели Вы поняли, что хотели и написали, то компиляторы современные тоже поймут. Debug и Release - с уровнями -O0 и -O3 Кроме этих "готовых рецептов" есть еще масса ключиков. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RabidRabbit 0 8 февраля, 2016 Опубликовано 8 февраля, 2016 · Жалоба На выравнивание pdwVal смотрите. Возможно при O0 компилятор не старается сложить всё по выравненным адресам... Налетал так со встроенным memcpy на Cortex-M0+ (хотя у Вас вроде без плюса). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Booger 0 8 февраля, 2016 Опубликовано 8 февраля, 2016 (изменено) · Жалоба В том то и дело, товарищи! Работает на всех уровнях оптимизации, кроме Leavel - 0 (O0). Я бы даже не сувался на форум, если было бы наоборот. При Leavel - 3 (O3) неудобно пользоваться "дебагером". Остальными уровнями (Leavel - 1 (O1) и Leavel - 2 (O2)) еще ни разу не пользовался. С одной стороны, конечно же хорошо, что всё отлично работает на 3-м уровне оптимизации, как все мы и добиваемся в конечном итоге, но хотелось бы докопаться до истины. Пока в голову ничего не пришло, как начать переписывать USB-шный пример, а может быть придется и всю библиотеку. ViKo, RabidRabbit, спасибо, буду смотреть. Изменено 8 февраля, 2016 пользователем Booger Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 8 февраля, 2016 Опубликовано 8 февраля, 2016 · Жалоба Смею предположить, что с включенной оптимизацией компилятор заменяет этот цикл на memcpy(), которая, в отличие от этого кода, корректно работает с невыровненными данными. При отключенной оптимизации, в зависимости от расположения pbUsrBuf, этот код может приводить к невыровненному доступу, который ядро M0 не поддерживает. За столько времени можно было эту маленькую функцию пройти в окне дизассемблера на любом уровне оптимизации, найти вызывающую падение ассемблерную команду и понять, откуда у нее берутся неправильные аргументы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Booger 0 9 февраля, 2016 Опубликовано 9 февраля, 2016 · Жалоба Спасибо всем за помощь! Действительно, если использовать memcpy, то работает и на 0-м уровне оптимизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться