Похоже, косяк был связан все-таки не с компилятором. Обнаружилось, что размеры стеков были заданы не кратными 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. Кто-нибудь про него знает чего-нибудь плохого?