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

 
 
> Errata IAR ARM 5.30, это точно компилятор))
zhek
сообщение Nov 23 2009, 10:53
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 29-12-05
Из: Екатеринбург
Пользователь №: 12 692



Начал подглючивать девайс при работе. Долго искал причины, пока не убедился, что это косяк IAR ARM 5.30. Делал оптимизацию High по Speed. Были установлены все птички, кроме Static clustering. Окончательно убедился, что это не ошибка в коде, когда стал регулярно ловить такую ситуацию. Ассемблерный код:
...
MOVNE R8,R8, LSL #+16
MOVNE R8,R8, ASR #+16
// 1740 if (a >= wbNOISE_PARTS)//фиксируем начало зубца
CMP R8,#+12
...
Команды MOVNE выполняют преобразование типа short->long. После этих операций в старших 16 битах может быть только знак, т. е. нули или единицы. Когда я ходил по ассемблерному коду, поймать не удавалось. А если идти по С-шному, то после очередного шага я сразу попадаю на строку CMP и вижу чудеса: например, в R8 вместо числа 58, лежат нули в младших 16 битах и число 25 в старших. Посмотрел, как используется R8 в прерываниях, но криминала не обнаружил. Так и не выяснил, что же именно происходит. Но поскольку использованием регистров рулит компилятор, то видимо из-за него когда-то что-то происходит не так.
После снятия галочки Function inlining в настройках оптимизатора все стало работать нормально.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
zltigo
сообщение Nov 23 2009, 10:57
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Слова-слова... А где, собственно тот самый не работающий сишный исходник и полученный из него листинг?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
zhek
сообщение Nov 23 2009, 11:13
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 29-12-05
Из: Екатеринбург
Пользователь №: 12 692



прикрепляю файлик, сменил расширение с .s на .txt, а то не позволяли прикрепить
строка 6922
Только код работает, смотреть его, наверное, неинтересно. Исходник не менялся полтора года, прошивка столько же работает в серийных изделиях. Я три дня по этому коду хожу. При одних и тех же начальных условиях функция может работать по-разному. А тот фрагмент, который написан выше, вроде как однозначно определяет содержимое R8.
Прикрепленные файлы
Прикрепленный файл  ecg_sel.txt ( 273.77 килобайт ) Кол-во скачиваний: 64
 
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 23 2009, 11:29
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(zhek @ Nov 23 2009, 14:13) *
Только код работает...

Ну тогда и смотреть не буду, если к коду претензий нет.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 23 2009, 11:48
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zhek @ Nov 23 2009, 13:13) *
фрагмент, который написан выше, вроде как однозначно определяет содержимое R8.
Может я чего-то не понимаю, но MOVNE выполняется именно когда NE. А если перед этим кодом получилось не NE, то эти команды не выполняются, и никакой однозначности в определении содержимого R8.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 23 2009, 11:57
Сообщение #6


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Сергей Борщ @ Nov 23 2009, 17:48) *
Может я чего-то не понимаю, но MOVNE выполняется именно когда NE. А если перед этим кодом получилось не NE, то эти команды не выполняются, и никакой однозначности в определении содержимого R8.

В этом месте в листинге всё в норме
Код
        CMP      R6,#+0
        RSBNE    R8,R8,#+0
        MOVNE    R8,R8, LSL #+16
        MOVNE    R8,R8, ASR #+16

Никакой неоднозначности. В зависимости от R6 у регистра R8 (signed short) будет сменён знак и опять преобразован к signed short (на всякий случай (+0x8000)).
---------
Насколько я успел мельком взглянуть, в листинге не видно баг и там не может быть старшие 16 бит R8 содержать число отличное от 0 или 0xffff.

Сообщение отредактировал GetSmart - Nov 23 2009, 11:58


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 23 2009, 15:13
Сообщение #7


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Одно только в этом коде выглядит подозрительным
Код
// 1737         {
// 1738         //определение амплитуды первого сегмента
// 1739         a = wbCalcDA(wv->ind_new, wv->ind_new, minus, wseg);
        MOV      R0,R10
        MOV      R2,R0
        MOV      R8,#+0
        B        ??wbWaveBuilder_15
...
??wbWaveBuilder_16:
        ADD      R3,R5,R2, LSL #+3
        LDRSH    R3,[R7, +R3]
        ADD      R8,R3,R8
        MOV      R8,R8, LSL #+16
        MOV      R8,R8, ASR #+16
        ADD      R2,R2,#+1
        AND      R2,R2,#0xFF
??wbWaveBuilder_15:
        CMP      R10,R2
        BCS      ??wbWaveBuilder_16
        CMP      R6,#+0
        RSBNE    R8,R8,#+0
        MOVNE    R8,R8, LSL #+16
        MOVNE    R8,R8, ASR #+16

При входе в цикл регистры R2 и R10 будут изначально равны и цикл по сути не выполнится ни разу. Видимо из-за первых двух одинаковых параметров на вызове
a = wbCalcDA(wv->ind_new, wv->ind_new, minus, wseg);

Если же есть явное подозрение на порчу R8, то это ещё может быть из-за неправильного сохранения/восстановления регистров в прерывании. Например прерывание обрабатывается в IRQ режиме, а обработчик оформлен с помощью __fiq атрибута. И ещё прикольный баг может быть - если вложенное прерывание некорректно восстанавливает флаги (SPSR->CPSR), например из-за проблем со стеком.

Сообщение отредактировал GetSmart - Nov 23 2009, 15:29


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zhek
сообщение Nov 24 2009, 09:44
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 29-12-05
Из: Екатеринбург
Пользователь №: 12 692



Цитата
При входе в цикл регистры R2 и R10 будут изначально равны и цикл по сути не выполнится ни разу

Тяжело дается ассемблер, но вроде как BCS - переход, если больше или равно, т. е. цикл выполнится 1 раз. Иначе вообще бы ничего не работало smile.gif
Это соответствует исходному коду функции wbCalcDA
Код
short wbCalcDA(UBYTE beg, UBYTE end, UBYTE minus, ecgWAVE_BUILD *wseg)
  {
  UBYTE i;
  short da;

  for (i = beg, da = 0; i <= end; i++)
    da += wseg->segs[i].da;
  if (minus) da = -da;
  return da;
  }


Цитата
Если же есть явное подозрение на порчу R8, то это ещё может быть из-за неправильного сохранения/восстановления регистров в прерывании.

Думаю, что это и есть самая вероятная причина. Но, глядя на листинг обработчиков прерываний, ничего подозрительного не нахожу. Правда, смотрел только на использование R8. Все смотреть тяжеловато, проект очень болшьой, а я с ассемблером на "Вы".
fiq в проекте не используется, вложенные прерывания - тоже
IAR показывает, что стеков хватает с запасом. Проверял (считал сам и смотрел на содержимое ОЗУ) - не врет.
Go to the top of the page
 
+Quote Post
Alechek
сообщение Nov 24 2009, 12:22
Сообщение #9


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

Группа: Свой
Сообщений: 1 241
Регистрация: 15-11-05
Из: Челябинск
Пользователь №: 10 882



Цитата(zhek @ Nov 23 2009, 16:53) *
Начал подглючивать девайс при работе. Долго искал причины, пока не убедился, что это косяк IAR ARM 5.30

Ну я знаю, что 5.30 косячный... Сам на грабли наступал при включении оптимизации: неверное переключение THUMB/ARM. smile3009.gif
А толку то возмущаться? Если есть 5.40? twak.gif
После перехода на него мои грабли исчезли.. disco.gif
Go to the top of the page
 
+Quote Post
zhek
сообщение Jul 8 2010, 09:01
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 29-12-05
Из: Екатеринбург
Пользователь №: 12 692



Похоже, косяк был связан все-таки не с компилятором. Обнаружилось, что размеры стеков были заданы не кратными 4. Из-за этого в прерываниях указатель стека тоже не был кратен 4. Если команда использовала указатель стека при адресации, 32-битные данные переписывались неправильно. Это сразу выявилось, когда локальные переменные в прерываниях стали типа int. Раньше использовались char и short. Разбираться, чтоб однозначно определиться с причиной, уже некогда. Т. к. в стеке может применяться выравнивание по 8 байт, теперь делаю размеры кратными 8 или 16.

Но вот сегодня столкнулся с другой проблемой - уже в IAR 5.40
Делаем расчет КИХ-фильтра, т. е. считаем свертку буфера сигнала с массивом коэффициентов. Без оптимизации все работает. Делаю оптимизацию High, Speed. Убираю галочки Function inlining и Static clustering. Получаю глюк. Ошибку видно в ассемблерном коде. Исходники на С и ассемблерный код прикладываю.

Суть ошибки в следующем. Буфер входного сигнала - кольцевой. Т. к. фильтр симметричный, умножений можно делать в два раза меньше. При расчете свертки движемся по буферу, используя два индекса, двигающихся в разных направлениях. Длина буфера 256 значений. На индексы надо накладывать маску 0xFF, чтобы "закольцеваться". Я для этого объявил индексы типом unsigned char.
Имеем цикл на С
for (i = 0; i < 128; i++)
{
x = f->buf[k1] + f->buf[k2];
sum += (long long)x*k2120v2[i];
k1++; k2--;
}
И ассемблерный код
// 66 x = f->buf[k1] + f->buf[k2];
// 67 sum += (long long)x*k2120v2[i];
??Lpf2120v2_1:
LDR R5,[LR, #+8]
ADD R6,R2,R3, LSL #+2
LDR R6,[R6, #+8]
ADD R5,R6,R5
LDR R6,[R12], #+4
SMLAL R0,R1,R5,R6
// 68 k1++; k2--;
SUB R3,R3,#+1
AND R3,R3,#0xFF
// 69 }
ADD LR,LR,#+4
SUBS R4,R4,#+1
BNE ??Lpf2120v2_1
в качестве переменной k2 используется R3 и с ним происходит все правильно
k1 в коде нет, вместо этого применяется указатель, который лежит в LR, и вот он-то выходит за пределы буфера и мы имеем глюк

Теперь надо пробовать новую версию IARа? Или сразу другой компилятор?
У нас некоторые разработчики используют Keil. Кто-нибудь про него знает чего-нибудь плохого?

Прикрепленные файлы
Прикрепленный файл  filters_dbg.txt ( 3.96 килобайт ) Кол-во скачиваний: 41
Прикрепленный файл  filters_dbg_h.txt ( 168 байт ) Кол-во скачиваний: 36
Прикрепленный файл  filters_dbg.s.txt ( 13.12 килобайт ) Кол-во скачиваний: 258
 
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 8 2010, 09:46
Сообщение #11


Гуру
******

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



Цитата(zhek @ Jul 8 2010, 13:01) *
в качестве переменной k2 используется R3 и с ним происходит все правильно
k1 в коде нет, вместо этого применяется указатель, который лежит в LR, и вот он-то выходит за пределы буфера и мы имеем глюк

Теперь надо пробовать новую версию IARа? Или сразу другой компилятор?
У нас некоторые разработчики используют Keil. Кто-нибудь про него знает чего-нибудь плохого?

Посмотрел в код - действительно глюк. Причём очень выпуклый: достаточно всего нескольких строчек кода, чтобы его вызвать.
Может быть, совпадение, но после того как я попытался обновить компилятор IAR Coldfire с 1.22 до 1.23, я столкнулся с генерацией некорректного кода. Пришлось откатиться обратно на 1.22. Похоже, что-то у IAR разладилось.
На самом деле от этого ни один компилятор не застрахован. Можно надеяться на популярность компилятора: если много людей используют, то глюков меньше. У Кейла компилятор - RealView от ARM. Кстати, очень популярный компилятор. Я как-то раз столкнулся с генерацией некорректного кода этим компилятором...
Go to the top of the page
 
+Quote Post
zhek
сообщение Jul 8 2010, 11:02
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 29-12-05
Из: Екатеринбург
Пользователь №: 12 692



Поизучал оптимизацию. Косяк возникает только если выбрана High оптимизация по Speed или Balance независимо от выбора галочек. Сделал High по Size. Все вроде нормально стало. Общая производительность упала процентов на 5-6. Устраивает.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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