|
Оптимизация в Keil |
|
|
|
Jul 21 2015, 18:24
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Всем привет! Использую Keil 5 для программирования STM32. Заметил интересную особенность. Выключаю оптимизацию (Level 0), запускаю код, в нем все прозрачно и безобидно - выделяется в функции локальная структура, и я ее заполняю. Выхожу из функции в main, захожу в другую функцию и отладчик отваливается с сообщением  Путем проб и ошибок выявил, что, закомментировав одно из заполнений полей структуры, Код struct.a = 0; struct.b = 100; struct.c = 45; // struct.d = 50; struct.e = 150; все работает. Т.е. поймал багу прямо на строчке заполнения структуры. Если перед объявлением структуры объявить еще что-нибудь, баг тоже исчезает... Подобного никогда не видел. При оптимизации Level 3 все работает, даже при заполнении всех полей структуры. Что там натворил оптимизатор такого? P.S. И еще вопрос. Почему при оптимизации Level 0 Код volatile const unsigned int a = 100; разместится в SRAM, а если она объявлена но не используется по коду - выкидывается вовсе из map-файла (ведь Level 0 предполагает ничего не оптимизировать)? Если просто Код const unsigned int a = 100; то все хорошо - константа будет во Flash. Для Level 3 вроде как оба случая разместят константу во Flash. Объясните, пожалуйста, или направьте на нужную информацию.
Сообщение отредактировал Arlleex - Jul 21 2015, 18:25
|
|
|
|
|
Jul 21 2015, 18:42
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125

|
Больше похоже на то что в камень заливается не то что собралось. Попробуйте делать полный ребилд проекта после смены уровня оптимизации. Иназвание переменной struct это реальное название или для примера?
Сообщение отредактировал Fedor - Jul 21 2015, 18:45
|
|
|
|
|
Jul 21 2015, 19:02
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Arlleex @ Jul 21 2015, 21:24)  отладчик отваливается Цитата(Arlleex @ Jul 21 2015, 21:49)  Еще один момент. Стоит вместо цифры 42 (в реальной железке) в этом поле структуры поставить число 128 - как код не зависает. Но это не выход из положения =) Так программа зависает, или отладчик отваливается? Это две большие разницы. Цитата(Arlleex @ Jul 21 2015, 21:24)  P.S. И еще вопрос. Почему при оптимизации Level 0 Код volatile const unsigned int a = 100; разместится в SRAM, а если она объявлена но не используется по коду - выкидывается вовсе из map-файла (ведь Level 0 предполагает ничего не оптимизировать)? Выкидывает линкер, а он не в курсе уровня оптимизации. Цитата(diwil @ Jul 21 2015, 21:54)  более того, я не совсем понимаю как воспринимать константу, которая _изменяется_ неизвестным компилеру способом... Например, RO-регистр периферии можно так объявить.
|
|
|
|
|
Jul 21 2015, 19:16
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(diwil @ Jul 21 2015, 21:54)  не совсем понимаю как воспринимать константу, которая _изменяется_ неизвестным компилеру способом... Слово "константа" здесь может ввести в заблуждение. Точнее будет "переменная, которой нельзя присвоить значение в программе". Значение всё равно может измениться: например, регистр датчика температуры. Цитата(Arlleex @ Jul 21 2015, 21:24)  Путем проб и ошибок выявил, что, закомментировав одно из заполнений полей структуры, ... все работает. Это не очень интересно. Гораздо интереснее будет, если удастся найти участок кода, при выполнении которого всё падает. Если по шагам не получается, то нужно ставить точку останова и двигать её, пока глюк не появится/пропадёт.
|
|
|
|
|
Jul 21 2015, 19:32
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Покажу на псевдокоде. Код int main(void) { func1(); // эта функция выполняется func2(); // при выполнении вот этой отладчик отваливается }
func1() { struct s;
s.a = 0; s.b = 10; s.c = 42; s.d = 50; init_struct(&struct); // ну, просто настраиваем регистры периферии микроконтроллера этой структурой }
func2() { // запись и чтение внешней памяти } Вот так - отладчик отваливается при попытке выполнения функции func2. Стоит закомментировать в func1 строку s.c = 42 или присвоить не 42 а 128 - отладчик не отваливается, функция выполняется. Пробовали 42, 128 и несколько других чисел - с некоторыми отваливается, с некоторыми - нет. Менял размер стека и кучи (ну, в отчаянии), не помогает. Само отваливание происходит при попытке записи во внешнюю память (при выполнении строчки что-то типа *(base_addr + addr) = data). Думаю, это не важно, ведь по сути абсурдно, что, изменив лишь инициализатор переменной, совсем не имеющей отношение к этой операции, результат будет разный - STLink отваливается, или нет. Кроме всего прочего. Если оставить так, что отладчик отваливается, и просто поменять порядок вызова функций (сначала func2, а потом func1) - отладчик не отваливается, память доступна и все счастливы =) Повторюсь. Это на уровне оптимизации Level 0. P.S. Отваливание отладчика еще и сопровождается "ввисанием" программы. Т.е. фактически я мониторю каждую выполненную функцию и после нее зажигаю светодиод. Так вот, если отладчик отваливается - не зажигается и светодиод. Когда я не под отладчиком, а просто прошил микроконтроллер и запустил на выполнение, все то же самое - светодиоды молчат. И где контроллер завис - не ясно. http://www.keil.com/forum/20367/Ссылка по теме. Правда у них ULINK.
Сообщение отредактировал Arlleex - Jul 21 2015, 19:45
|
|
|
|
|
Jul 21 2015, 19:42
|
Участник

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125

|
Если структуру struct s; объявить глобальной или static отваливается?
|
|
|
|
|
Jul 22 2015, 07:21
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Arlleex @ Jul 21 2015, 21:24)  ...Использую Keil 5 для программирования STM32.... по внешним признакам было что то подобное с кейлом, под 51 мк. правда там не си а азм юзал, но суть следующая = тупо изменялся азм на выходе компилятора. т.е. я нашёл место различия(пара-тройка байт где-то), и после модификации исходников, компиляции - лез в промежуточные файлы = оно родимое. так-же плавало, так-же влияло и до/после вставка/удаление. вообще не связанное с исходником код. хоть левое, хоть правое - одно цветом. списал на глюк кейла. т.к. не официальная версия - тупо сообщил на форум просто. т.к. проект корректировался дальше - забил. прогоны сбоев не дали. осадочек остался  PS Да, год этак 2005 где-то...
Сообщение отредактировал kolobok0 - Jul 22 2015, 07:21
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|