ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
26 ноября
971259
Nikolay_Po (17.01.2020 18:18 - 20.01.2020 18:35, просмотров: 29479)
[РЕШЕНО] GNU Tools for STM32 7-2018-q2-update (и вообще любой arm-none-eabi). Не могу добиться появления глобальных массивов в *.map Спасибо всем за помощь и участие! Проблема была в логическом уровне на выводе BOOT0 чипа STM32F107VCT6. Переключатель отладочной платы оказался в неверном положении. Чип стартовал с загрузчика и, уже с неверным значением указателя стека, в режиме отладки, начиналось выполнение основной программы. Это создало массу проблем с Hard_Fault и прочими исключениями. После перключения режима загрузки из "SYSTEM" во "FLASH" проблема со стеком ушла и я быстро нашёл перепутанные местами индексы. Всё заработало, самый-самый первый Hard_Fault побеждён. Развиваю код дальше. Ниже исходная просьба о помощи. Перепробовал разные компиляторы, почти разные IDE и разные шаблоны проектов. Вот такая проблема. Где я туплю? Есть четыре файла исходников:
  • custom_adc.h,
  • custom_dsp.h,
  • custom_adc.c и
  • custom_dsp.c.
  • В файле custom_dsp.с, вне функции определён буфер для входных данных многоканального фильтра: volatile int16_t Stage1Buff[2][ADCchNum][St1BuffSize] = { { { 0 } } }; //Input buffer for ADC data flow В заголовочном custom_dsp.h, чтобы в этот буфер код АЦП смог внести данные замеров, объявлено следующим образом: extern volatile int16_t Stage1Buff[2][ADCchNum][St1BuffSize]; //Input buffer for ADC data flow Буфер пинг-понг. Для справки, ADCchNum 17, St1BuffSize 64. Модификатор volatile поставил, так как доступ к данным идёт из разных контекстов - из функций ЦОС и из функции АЦП. И данные для контекста ЦОС могут меняться вне кода ЦОС. Чтобы код АЦП мог разложить свежие данные из буфера DMA (16+1 замер за раз) в буферы каналов (17 каналов по 64 отсчёта), в код custom_adc.c включён заголовок custom_dsp.h. Таким образом, функции custom_adc.c "видят" буфер Stage1Buff[][][]. Запись в буфер Stage1Buff идёт в прерывании, примерно таким образом (ниже код из custom_adc.c): // Обёртка записи в буфер для проверки диапазонов индексов (от безысходности и в целях отладки) // Буфер не является аргументом функции, обращение к нему идёт как к глобальному объекту void WriteSt1buff(int Side, int Channel, int Sample, int16_t Data) { //Sanity checks if ((Side < 0) || (Side > 1)) { while (1) { asm volatile ("nop"); } } if ((Channel < 0) || (Channel >= ADCchNum)) { while (1) { asm volatile ("nop"); } } if ((Sample < 0) || (Sample >= St1BuffSize)) { while (1) { asm volatile ("nop"); } } Stage1Buff[Side][Channel][Sample] = Data; } А вот код внутри функции-прерывания АЦП: //Move ADC data into filter's buffer for (int Ch = 0; Ch < ADCregCh; Ch++) { //Move DMA channels WriteSt1buff(St1status.Side, Ch, St1status.WriteIdx, ADCbuff[Ch]); } Отладка показывает, что ADCbuff[Ch] содержит корректные данные отсчётов АЦП. Мало того, часть буфера Stage1Buff[][][], первая половина полностью, вторая - в первых пяти каналах (до сбоя) содержит корректные данные после соответствующего количества прерываний. Но код вылетает в HardFault и видно, как данные во второй половине буфера частично затираются, а запись в буфер сама затирает важные данные в ОЗУ. Симптомы те же, что и тут http://caxapa.ru/968602.html. Только сменил IDE с Eclipse на STM32CubeIDE (почти одно и то же, но работает с кубовым шаблоном лучше) и компилятор в CubeIDE чуть другой. Посмотрел *.map. Поиск в этом файле не находит ни одного упоминания Stage1Buff. Его просто нет в карте памяти, а работа с буфером рано или поздно (практически - на заполнении второй половины) рушит программу, так как данным АЦП затирается (предположительно) стек. Глянте пожалуйста, ЧЯДНТ? Спасибо.