реклама на сайте
подробности

 
 
6 страниц V  « < 2 3 4 5 6 >  
Reply to this topicStart new topic
> Странное предупреждение
juvf
сообщение Jun 21 2018, 10:50
Сообщение #46


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(jcxz @ Jun 21 2018, 15:18) *
При отладке одно из главнейших правил: ПРИ ПРОЯВЛЕНИИ БАГА НЕ СЛЕДУЕТ СТАРАТЬСЯ ДОБИТЬСЯ ТОГО, ЧТОБЫ ОН НЕ ПРОЯВЛЯЛСЯ. НАДО НАОБОРОТ - ЗАКРЕПИТЬ УСЛОВИЯ, ПРИ КОТОРЫХ ОН ПРОЯВЛЯЕТСЯ, ДОБИТЬСЯ ЕГО ПОВТОРЯЕМОСТИ И ИСКАТЬ ЕГО ПРИЧИНУ И УСТРАНИТЬ! И пока этого не сделано - двигаться дальше нельзя.
так я нашел причину и устранил. ))

inline void waitSpi() { while( (SPI1->SR & (uint8_t)SPI_FLAG_BSY));} - вот этот код не работает с оптимизацией в пустом хороводе. И не изредка - а всегда. 100 раз из 100. А без оптимизации работает как часы. ни каких сбоев в обмене по SPI замечено не было.

Цитата
Ведь не тот баг страшен, который чётко проявляется, а тот - что проявляется иногда, внезапно и хаотично.
У меня црц считается с ошибкой всегда, когда вкл оптимизация, не изредка, а всегда. И всегда считается правильно с отключенной оптимизацией. Нету хаотичных и внезапных сбоев.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Jun 21 2018, 11:02
Сообщение #47


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Любопытства ради и самообразования для, не могли бы вы привести код црц и чем копилируете?
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 21 2018, 11:04
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(juvf @ Jun 21 2018, 13:50) *
inline void waitSpi() { while( (SPI1->SR & (uint8_t)SPI_FLAG_BSY));} - вот этот код не работает с оптимизацией в пустом хороводе. И не изредка - а всегда. 100 раз из 100. А без оптимизации работает как часы. ни каких сбоев в обмене по SPI замечено не было.

Я так понимаю, версия про "volatile" была проверена и не подтвердилась? Опять же, конкретно в этом случае чтение листинга дизассемблера не затруднило бы нисколько. Из оправданий - только лень.
Кстати, бывают баги, зависящие от задержек. Скажем, регистр SPI1->SR нужно начинать читать не сразу, а через пару тактов, без оптимизации задержка получалась сама собой - как вариант.
Go to the top of the page
 
+Quote Post
juvf
сообщение Jun 21 2018, 11:06
Сообщение #49


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(Kabdim @ Jun 21 2018, 16:02) *
Любопытства ради и самообразования для, не могли бы вы привести код црц и чем копилируете?

читайте выше. там и код и чем компилирую.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 21 2018, 11:06
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(juvf @ Jun 21 2018, 13:24) *
ээээ.... а разве при переполнении стека программа аварийно не завершается?

При переполнении стека симптомы могут быть какие угодно: может fault вылететь, а могут просто данные испортиться.

Цитата(juvf @ Jun 21 2018, 13:24) *
А без оптимизации шагается но и работает без ошибок.

Я уже писал выше что можно сделать. Скомпилить данную функцию с оптимизацией. А потом вырезать её ассемблерный листинг и вставить в код компилируемый без оптимизации (как асм-функцию). И проверить работу кода теперь.
И по асму шагать не надо, надо выучить ассемблер и "глазами" аналитически сравнить си-исходник с асм-результатом. И только если в этом случае будут найдены несоответствия между ними - только в этом случае можно однозначно говорить о вине компилятора.

Цитата(juvf @ Jun 21 2018, 13:24) *
Что-то я не пойму.... Вот, вы же сами утверждаете, что оптимизатор может сломать работу программы написанной без ошибок. Я о том же.

Если Вы считаете, что в недостаточном объёме выделенной под стек памяти виноват оптимизатор, а не "пейсатель" кода, то больше разговаривать не о чем..... smile3046.gif
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 21 2018, 11:09
Сообщение #51


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jun 21 2018, 14:06) *
И по асму шагать не надо, надо выучить ассемблер и "глазами" аналитически сравнить си-исходник с асм-результатом. И только если в этом случае будут найдены несоответствия между ними - только в этом случае можно однозначно говорить о вине компилятора.

Советую взять современный GCC и дать ему ключики -Os -flto. При любом более-менее нетривиальном коде "аналитическое сравнение" легко способно перейти в бессонные ночи biggrin.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 21 2018, 11:12
Сообщение #52


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(adnega @ Jun 21 2018, 13:25) *
компилятор генерит правильный s-файл. Иначе генерит таблицу, в которой смещения не помещаются.
Где тут моя ошибка? Где ошибка компилятора я разобрался и на всякий случай сменил компилятор (была сборка arm-kgp-eabi-procyon).

Из Вашего описания я понял, что асм-файл писали Вы сами....
Для таких малопопулярных ядер как ESP8266, вполне допускаю что компилятор гораздо более сырой, чем для main stream Cortex-M например.

Цитата(scifi @ Jun 21 2018, 14:09) *
Советую взять современный GCC и дать ему ключики -Os -flto. При любом более-менее нетривиальном коде "аналитическое сравнение" легко способно перейти в бессонные ночи biggrin.gif

У juvf функция очень тривиальная и маленькая. В худшем случае будет бессонный час. laughing.gif
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 21 2018, 11:13
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jun 21 2018, 14:10) *
Для таких малопопулярных ядер как ESP8266, вполне допускаю что компилятор гораздо более сырой, чем для main stream Cortex-M например.

Пожалуйста, похожая история с Cortex-M: тыц.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 21 2018, 11:19
Сообщение #54


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(juvf @ Jun 21 2018, 13:50) *
У меня црц считается с ошибкой всегда, когда вкл оптимизация, не изредка, а всегда. И всегда считается правильно с отключенной оптимизацией. Нету хаотичных и внезапных сбоев.

Это не устранение причины. Это как вместо лечения причины болезни, бороться с её симптомами.
Если Вы подозреваете, что виноват компилятор, то устранение бага в таком случае - замена компилятора. Ведь если он косячит в данной функции, то где гарантия что не косячит в других местах? Просто эти косяки сейчас не проявляются (например - по этим веткам ветвления не проходит управление, но при каком-то стечении обстоятельств в будущем оно пройдёт и баг получит уже пользователь).
Но вину компилятора сперва нужно однозначно доказать.
Go to the top of the page
 
+Quote Post
juvf
сообщение Jun 21 2018, 11:19
Сообщение #55


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(jcxz @ Jun 21 2018, 16:06) *
При переполнении стека симптомы могут быть какие угодно: может fault вылететь, а могут просто данные испортиться.
я же писал, данные не портятся, в фолаут не вылетаю, а црц считает с ошибкой.

Цитата
Если Вы считаете, что в недостаточном объёме выделенной под стек памяти виноват оптимизатор, а не "пейсатель" кода, то больше разговаривать не о чем..... smile3046.gif
Я достаточно выделил памяти на стек. Без оптимизации глубины стека хватает с запасом. Если оптимизатор удвоил запросы ОЗУ на стек, то мне такой оптимизатор не нужен. laughing.gif
Во вторых, бывало вылазил за стек.... на разных проекта.... либо фолаут, либо данные портились. Это быстро обнаруживается. Тут идет подсчет црц, но неправильный. Ни чего не портиться и не падает.

Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 21 2018, 11:22
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jun 21 2018, 14:13) *
Пожалуйста, похожая история с Cortex-M: тыц.

Да я не спорю, что и в компиляторах есть косяки. Я даже сам несколько лет назад выкладывал сюда на форум описание одного из них.
Но я чётко доказал, что это именно косяк компилятора (это был IAR вроде v6.20 или v6.40).
И выложил и фрагмент си-кода и результат компиляции (ассемблер) и ключи компиляции, при которых этот результат получен. Чтобы каждый смог лично проверить.
Go to the top of the page
 
+Quote Post
juvf
сообщение Jun 21 2018, 11:46
Сообщение #57


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(jcxz @ Jun 21 2018, 16:19) *
Ведь если он косячит в данной функции, то где гарантия что не косячит в других местах?
Нет гарантии. Все места проверяются глубоким тестированием. А если компилятор оптимизатор не косячит - то нет ни какой гарантии, что нет косяков пейсателя/компилятора в других местах. Все места проверяются глубоким тестированием, стрестестами и т.п. , Это касается любого компилятора/оптимизатора, любого кода.


Цитата(scifi @ Jun 21 2018, 16:04) *
Я так понимаю, версия про "volatile" была проверена и не подтвердилась? ....
конечно первым делом volatile.
Цитата
SPI1->SR нужно начинать читать не сразу, а через пару тактов, без оптимизации задержка получалась сама собой - как вариант.
Чуть не написал "Слона не увидел", но слона нет. Во первых в даташите про это ни чего не говориться, во вторых.... сначала готовлю данные, потом их отправляю в спи, не дожидаясь завершения ..... на русском сложно писать, написшу на си

Код
sleepMs(1000);
for()
{
//подготовка данных
waitSpi();
//запись данных в спи регистр.
}

в waitSpi() с оптимизацией не задерживаюсь ни когда, а должен не задерживаться только первый раз. После отправки данных до чтения регистра SPI1->SR проходит много времени, но меньше, чем выход 8 бит в спи.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 21 2018, 11:48
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(juvf @ Jun 21 2018, 13:50) *
inline void waitSpi() { while( (SPI1->SR & (uint8_t)SPI_FLAG_BSY));} - вот этот код не работает с оптимизацией в пустом хороводе. И не изредка - а всегда. 100 раз из 100. А без оптимизации работает как часы. ни каких сбоев в обмене по SPI замечено не было.

Описание типов данных, какое ядро/МК, описание SPI_FLAG_BSY и декларации SPI1 где? Асм-результат с оптимизацией где?
Или с декларациями что-то не так или у вас в этом коде например гонки или куча других причин. laughing.gif
И опять - пример никак не свидетельствует о вине компилятора.
Вот приведу такой случай из своей практики:
Писал я как-то под CC5502 (TI DSP). Был простейший цикл типа Вашего выше: просто в цикле опрашивался флаг, типа: while (!flag);
Этот flag в состояние !=0 устанавливался в ISR завершения DMA-транзакции (цикл ждал завершения DMA).
И вот у меня возникла ситуация подобная Вашей: без оптимизации или с минимальной оптимизацией всё работает, а с полной оптимизацией - виснет в бесконечном ожидании в этом цикле и через некоторое время вылетает в bus-fault в DMA-контроллере. А дальше стало ещё хуже - выяснилось, что при добавлении/убирании строчек кода из совершенно других мест си-исходника, этот код иногда начинает работать. Причём работать 100%! Но при следующем редактировании исходника опять начинает падать в bus-fault (внимание adnega - очень знакомое поведение, не правда-ли? rolleyes.gif )

Видимо Вы бы уже сложили ручки и обвинили во всём компилятор. Но я продолжил рыть. И в конце-концов нашёл причину!
Оказалось, что при полной оптимизации код цикла получался такой короткий и быстрый, что CPU всё время был занят подкачкой команд в буфер предвыборки, только загрузил в конвеер команду условного перехода, пока грузил следующий пакет предвыборки за ней, то команда успевала выполниться, шёл сброс конвеера и загрузки предвыборки из начала цикла. Вобщем - тело цикла было длиной всего 2-3 такта. И если получалось что тело цикла располагалось на границе сегментов предвыборки (смещение начала цикла в памяти & 3 было == определённым значениям), то процессор полностью загружал шину к памяти своими запросами. А у него приоритет доступа к шине был выше чем у DMA-контроллера. DMA-контроллер считав данные из периферии, делал 512 попыток запроса доступа к шине ОЗУ у арбитра, не получал доступа и в конце концов останавливал работу с выставлением fault-а.
При добавлении/удалении строк кода в разных местах исходника, весь код сдвигался, соответственно - чтение тела цикла иногда влезало в 1 сегмент prefetch (требовало на 1 такт меньше времени) и код чудесным образом начинал работать (DMA-контроллер в этот 1 освободившийся такт успевал пролезть на шину и записать данные в ОЗУ).

Вот такой пример из практики. И что же - тут виноват компилятор? Нет, виноват конечно был я - не надо было располагать DMA-буфер и код в одном сегменте ОЗУ (МК не позволял задать для DMA приоритет доступа к шине выше чем CPU) laughing.gif
Go to the top of the page
 
+Quote Post
adnega
сообщение Jun 21 2018, 12:01
Сообщение #59


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(jcxz @ Jun 21 2018, 14:12) *
Из Вашего описания я понял, что асм-файл писали Вы сами....

Как телепат телепату, откройте секрет, где в моем сообщении можно хоть как-то прийти к такому выводу?
В строчке
make.EXE: *** [obj_sw/esp8266.o] Error 1
видим, что не собирается цель esp8266.o
А ошибку видим в s-файле с роботским именем C:\Users\user\AppData\Local\Temp\ccShzzAY.s в месте похуже корзины.
Т.е. вы решили, что мой проект лежит в Temp, я сам написал asm-файл и дал ему имя ccShzzAY.s, а затем как-то
заставил компилятор ругаться при сборке esp8266.o причем русским языком ниже сказано про Си-исходник? КАК?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 21 2018, 12:11
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(juvf @ Jun 21 2018, 14:46) *
в waitSpi() с оптимизацией не задерживаюсь ни когда, а должен не задерживаться только первый раз. После отправки данных до чтения регистра SPI1->SR проходит много времени, но меньше, чем выход 8 бит в спи.

Как одна из возможных причин:
Загружаете данные в буферный регистр SPI. Флаг DLY при этом не выставляется. А выставляется он только после того, как данные из буфера попадут в сдвиговый регистр. А попадут они туда после того как пройдёт некая задержка от завершения предыдущего SPI-фрейма (предыдущего поднятия CS=high), выдержки межфреймовой паузы (при CS=high), выдержки паузы после CS=fall и началом первого клока SCLK. Вот в этот момент возможно данные переместятся в сдвиговый регистр и выставится флаг DLY.
Т.е. - от момента записи данных в буферный регистр SPI до момента выставления флага DLY может пройти существенное время (в зависимости от частоты SCLK). А у Вас в программе возможно вы после записи очередной порции данных в буферный регистр SPI сразу переходите к waitSpi() и считаете что данные уже передались (так как флага нет), а они по-настоящему ещё и не начинали передаваться.
При запрете оптимизации же, код выполняется медленнее и DLY успевает выставиться, поэтому и работает.

Вот такой тип багов и называется "гонки". Как я выше и писал. И он конечно ваш, а не оптимизатора. laughing.gif

PS: Это как возможный вариант причины бага. Причина может быть и другой. Так как всего кода я не вижу и как работает SPI в вашем МК - не знаю.

Цитата(adnega @ Jun 21 2018, 15:01) *
А ошибку видим в s-файле с роботским именем C:\Users\user\AppData\Local\Temp\ccShzzAY.s в месте похуже корзины.
Т.е. вы решили, что мой проект лежит в Temp, я сам написал asm-файл и дал ему имя ccShzzAY.s, а затем как-то
заставил компилятор ругаться при сборке esp8266.o причем русским языком ниже сказано про Си-исходник? КАК?

Я не смотрю на имена файлов тем более пути. Достаточно только расширения. И про си-исходник там сказано только что что-то в нём меняете. Как вариант: после смены там функция становится больше, перемещается в другое место в памяти и эта функция вызывается из асм между метками .L274, .L276 - и команда вызова становится длиннее и расстояние между .L274 и .L276 увеличивается.

PS: Если хотите чтобы Вас понимали однозначно, излагайте свои мысли ясно.
Go to the top of the page
 
+Quote Post

6 страниц V  « < 2 3 4 5 6 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th June 2025 - 23:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.02213 секунд с 7
ELECTRONIX ©2004-2016