|
Errata IAR ARM 5.30, это точно компилятор)) |
|
|
|
Nov 23 2009, 10:53
|
Участник

Группа: Участник
Сообщений: 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 в настройках оптимизатора все стало работать нормально.
|
|
|
|
|
 |
Ответов
|
Jul 8 2010, 09:01
|
Участник

Группа: Участник
Сообщений: 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. Кто-нибудь про него знает чего-нибудь плохого?
|
|
|
|
|
Jul 8 2010, 09:46
|
Гуру
     
Группа: Свой
Сообщений: 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. Кстати, очень популярный компилятор. Я как-то раз столкнулся с генерацией некорректного кода этим компилятором...
|
|
|
|
Сообщений в этой теме
zhek Errata IAR ARM 5.30 Nov 23 2009, 10:53 zltigo Слова-слова... А где, собственно тот самый не рабо... Nov 23 2009, 10:57 zhek прикрепляю файлик, сменил расширение с .s на .txt,... Nov 23 2009, 11:13 zltigo Цитата(zhek @ Nov 23 2009, 14:13) Только ... Nov 23 2009, 11:29 Сергей Борщ Цитата(zhek @ Nov 23 2009, 13:13) фрагмен... Nov 23 2009, 11:48  GetSmart Цитата(Сергей Борщ @ Nov 23 2009, 17:48) ... Nov 23 2009, 11:57 GetSmart Одно только в этом коде выглядит подозрительным
Ко... Nov 23 2009, 15:13 zhek ЦитатаПри входе в цикл регистры R2 и R10 будут изн... Nov 24 2009, 09:44 Alechek Цитата(zhek @ Nov 23 2009, 16:53) Начал п... Nov 24 2009, 12:22 zhek Поизучал оптимизацию. Косяк возникает только если ... Jul 8 2010, 11:02
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|