Nikolay_Po (04.01.2020 00:44 - 00:52, просмотров: 366) ответил SciFi на У меня GNU ARM Embedded "8 2019-q3-update". Это предпоследний. У себя проблем пока не видел, да и багрепортов про него особо не видел. Последний релиз не завлекает крутыми фичами, багрепорты уже есть. Это для наркоманов, подсевших на "самый-самый
Попался! Целый день потратил. Пока непонятно, или проблема в параметрах компиляции (упущено что-то принципиально важное для платформы) или инструментарии "GNU Arm Embedded Toolchain" arm-none-eabi-gcc (15:5.4.1+svn241155-1) 5.4.1 20160919. Проблема проявляется так. В файле "main.c" глобально определена пара буферов:
volatile q15_t Stage1Buff[2][CellChNum][Buff1Size] = { 0 };
q15_t Stage2Buff[2][CellChNum][Buff2Size] = { 0 };
И в тексте main() (глобально тоже не работает, перенёс в main в порядке эксперимента) определены массив структур и массив памяти фильтров:
arm_fir_decimate_instance_q15 Stage1Inst[CellChNum] = { 0 }; //Stage 1 filter's instances
q15_t Stage1state[CellChNum][47 + Buff1Size - 1] = { 0 }; //Stage 1 filter's state memory
Проблема проявляется так: в *.map сборки указаны позиции буферов Stage1Buff и Stage2Buff. С ними проблем нет.
Структуры и память фильтров, пока нет записи в буферы, инициализируются соответствующим кодом нормально, содержат корректную информацию. В отладчик видно - всё норма. Но через несколько циклов обработки, программа вылетает в Hard Fault. Локализовал проблему в не верных данных структуры фильтров. Часть членов массива структур фильтров затёрты нулями или ерундой, предположительно, из буферов.
Отладочная информация по переменным, отображаемая Eclipse, показала, что адреса буферов и структур/памяти фильтров перекрываются. Структур и памяти фильтров в файле *.map не упоминается вообще никак. Примечательно, что в качестве начала отчёта адреса того или иного члена проблемного массива, в отладке виден стартовый адрес одного из буферов плюс смещение, а не адрес структуры.
Не работает даже при -O0.
Пример использования в main() (корректность индексов проверял в разных вариантах):
//Initialize FIR low pass filters
for (int Ch = 0; Ch < CellChNum; Ch++) {
//Stage 1 filters
arm_fir_decimate_init_q15(
(arm_fir_decimate_instance_q15*) &Stage1Inst[Ch], //Filter instance
47, //Number of taps
4, //Decimation factor
Stage1Coeff, //FIR coefficients
Stage1state[Ch], //Filter memory
Buff1Size);
}
volatile int SrcHalfIdx = !Stage1Flags.BuffSide;
volatile int DstHalfIdx = Stage2Flags.BuffSide;
volatile int DstSmpIdx = Stage2Flags.WriteIdx;
for (int Ch = 0; Ch < CellChNum; Ch++) { //Scan through the channels while filtering stage 1 chunks
volatile const arm_fir_decimate_instance_q15 *Instance = &Stage1Inst[Ch];
volatile const q15_t *SourcePtr = (q15_t*) Stage1Buff[SrcHalfIdx][Ch];
volatile q15_t *DestinationPtr = &Stage2Buff[DstHalfIdx][Ch][DstSmpIdx];
if ((Instance < &Stage1Inst[0])
|| (Instance > &Stage1Inst[CellChNum - 1])) {
while (1) {
asm volatile ("nop");
}
}
if ((SourcePtr < &Stage1Buff[0][0][0])
|| (SourcePtr > &Stage1Buff[1][CellChNum - 1][0])) {
while (1) {
asm volatile ("nop");
}
}
if ((DestinationPtr < &Stage2Buff[0][0][0])
|| (DestinationPtr
> &Stage2Buff[1][CellChNum-1][Buff2Size - Buff1Size / 4])) {
while (1) {
asm volatile ("nop");
}
}
arm_fir_decimate_fast_q15(Instance, //Use separate filter instance for each channel
SourcePtr, //Channel values at input
DestinationPtr, //Store output to second stage
Buff1Size); //Use block size of whole stage 1 buffer side
}