Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Непонятные ошибки при компиляции
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
allsettingsdone
Здравствуйте, пишу значит для STMF4 в коксе, столкнулся с необъяснимыми ошибками вида "Error: offset out of range" на казалось бы совсем нормальных местах (см. скриншот и приложенный код). Возможно кто сталкивался с таким да поможет или хотя бы намекните что это может быть?
Genadi Zawidowski
-O0 совместно с -flto смотрится просто поразительно...
Вы или -Os поставьте или -flto уберите.
Может помочь. Если не поможет, то хоть узнаете откуда неправильный ассемблерный код появился - программист вставил или компилятор нагенерировал.
Zol'berg
Всем привет, я новичок на этом форуме и являюсь причиной описанного в данной теме (попросил друга выложить), сразу извиняюсь за не подготовку вопроса должным образом, а если по теме, то..
Отрабатывал инициализацию и работу в отдельных проектах SPI,DMA,GPIO,EXTILine0, по отдельности усе работает laughing.gif ,если собрать до кучи SPI,DMA,GPIO, то тоже нормально работает, добавляю EXTILine0, вылетает эта ошибка, если же при этом убрать SPI, то вновь работает, и подобные заклинания в непонятной зависимости влияют на проект в целом с этой стороны. Чуть раньше было такое, когда объявления типа "GPIO_InitTypeDef GPIO_InitStructure" и "DMA_InitTypeDef DMA_InitStructure" были "вверху проекта", для всех функций (глобальные) - та же ошибка, шаманил, шаманил и перенес их в каждую функцию отдельно, в голове мысль "разницы не должно быть" и это настораживает, но факт, что помогло wacko.gif .
В консоли CooCox увидел "-Os" и "-flto" описанные Вами выше, но что это такое и как с этим бороться не имею и представлений, не могли бы Вы мне разъяснить, заранее спасибо biggrin.gif .
P.S. Если нужно, в целях прозрачности понимания могу очистить проект от неиспользуемого кода и мусора и выложить)).
Сергей Борщ
Добро пожаловать.
Для начала отключите -flto. Если поможет - обновляйте компилятор или так и оставьте с отключенной. Оптимизация свежая, все может быть. Если не поможет, читайте дальше.
QUOTE (Zol'berg @ May 8 2013, 09:37) *
и подобные заклинания в непонятной зависимости влияют на проект
Хорошо бы посмотреть на этот ассемблерный файл. Добавьте в ключи компилятора -save-temps и найдите этот файл.

QUOTE (Zol'berg @ May 8 2013, 09:37) *
были "вверху проекта", для всех функций (глобальные) - та же ошибка, шаманил, шаманил и перенес их в каждую функцию отдельно, в голове мысль "разницы не должно быть" и это настораживает, но факт, что помогло wacko.gif .
Если вы не понимаете разницы между глобальными и автоматическими переменными, то это действительно шаманство. А авторы "примеров" к "библиотекам" ее тоже, похоже, не понимают. Их примеры - отличный образец как сделать быстрое железо медленным.
QUOTE (Zol'berg @ May 8 2013, 09:37) *
В консоли CooCox увидел "-Os" и "-flto" описанные Вами выше, но что это такое и как с этим бороться не имею и представлений
Ройтесь по менюшкам, ищите галочки или выпадающие списки с такими или похожими названиями (-flto может называться Link-time optimization). Эти опции связаны с оптимизацией.
Genadi Zawidowski
Уточняю - не намёками а прямо: -O0 совместно с -flto иногда генерят неправильный ассемблерный код. -Os используйте.
Zol'berg
Порылся в CooCox везде, по поводу -flto ничего не нашел, а вот -O0 есть, и если выбрать любые из -O1,-O2,-O3,-Os, то компилируется нормально)).
Нажмите для просмотра прикрепленного файла
Нажмите для просмотра прикрепленного файла
Что делать дальше, оставить как есть, -flto и -O1 ?
Сергей Борщ
QUOTE (Zol'berg @ May 8 2013, 11:08) *
Что делать дальше, оставить как есть, -flto и -O1 ?
А что вы хотите получить в результате? Быстрый код? Маленький код? Просто чтобы влезал в контроллер? Выбирайте. Если хотите быстрый или маленький код - избавляйтесь от "библиотек".
Zol'berg
Цитата(Сергей Борщ @ May 8 2013, 10:00) *
Если вы не понимаете разницы между глобальными и автоматическими переменными, то это действительно шаманство. А авторы "примеров" к "библиотекам" ее тоже, похоже, не понимают. Их примеры - отличный образец как сделать быстрое железо медленным.

Глобальные и локальные переменные мне знакомы, работают по разному, но суть одна-в том, что работать должно и так и так ( и глобальные для всех функций инициализации и локальные - в каждой функции свои), а по поводу "медленных примеров", я не только/только начал изучение STM32, для меня и C нов, т.к. ранее работал с AVR на ассемблере! А как сделать быстрее, писать конфигурацию прямо в регистры?

В моем проекте инициализацию можно провести медленно.
Но есть другой вопрос, уже наверное не по теме : как добиться быстрой работы с портами, ассемблерные вставки? Так не могу найти описания этих самых команд для STM32F4! Может есть темы на эту тему?))
Сергей Борщ
QUOTE (Zol'berg @ May 8 2013, 11:42) *
Глобальные и локальные переменные мне знакомы, работают по разному, но суть одна-в том, что работать должно и так и так
Уже разобрались - это была внутренняя ошибка компилятора.
QUOTE (Zol'berg @ May 8 2013, 11:42) *
А как сделать быстрее, писать конфигурацию прямо в регистры?
Да. Причем сразу, одной командой, а не десятком дерганий каждого битика по отдельности, чем страдает вторая категория примеров из интернета. Вот, сравните, пример по ссылке из соседней ветки:
CODE
  ADC1->CR1     =  0;                    //предочистка регистра
  ADC1->CR2    |=  ADC_CR2_CAL;          //запуск калибровки
  while (!(ADC1->CR2 & ADC_CR2_CAL)){};  //ждем окончания калибровки
  ADC1->CR2     =  ADC_CR2_JEXTSEL;      //выбрать источником запуска разряд  JSWSTART
  ADC1->CR2    |=  ADC_CR2_JEXTTRIG;     //разр. внешний запуск инжектированной группы
  ADC1->CR2    |=  ADC_CR2_CONT;         //режим непрерывного преобразования
  ADC1->CR1    |=  ADC_CR1_SCAN;         //режим сканирования (т.е. несколько каналов)
  ADC1->CR1    |=  ADC_CR1_JAUTO;     //автомат. запуск инжектированной группы
  ADC1->JSQR    =  (uint32_t)(4-1)<<20;  //задаем количество каналов в инжектированной группе
  ADC1->JSQR   |=  (uint32_t)3<<(5*0);   //номер канала для первого преобразования            
  ADC1->JSQR   |=  (uint32_t)4<<(5*1);   //номер канала для второго преобразования
  ADC1->JSQR   |=  (uint32_t)5<<(5*2);   //номер канала для третьего преобразования
  ADC1->JSQR   |=  (uint32_t)6<<(5*3);   //номер канала для четвертого преобразования
  ADC1->CR2    |=  ADC_CR2_ADON;         //включить АЦП
  ADC1->CR2    |=  ADC_CR2_JSWSTART;     //запустить процес преобразования
Вам, как недавнему ассемблеристу довольно просто посчитать сколько здесь чтений регистра периферии, сколько наложений масок и записей.
Теперь смотрите сюда:
CODE
// calibrate ADC
ADC1->CR2 = 0
| 1 * ADC_CR2_ADON // A/D Converter ON
| 0 * ADC_CR2_CONT // Continuous Conversion disabled
| 1 * ADC_CR2_CAL // A/D Calibration
| 0 * ADC_CR2_RSTCAL // Reset Calibration
| 0 * ADC_CR2_DMA // Direct Memory access mode
| 0 * ADC_CR2_ALIGN // Data Alignment: right
| 0 * ADC_CR2_JEXTSEL_0 // External event for injected group: none
| 7 * ADC_CR2_JEXTTRIG // External Trigger Conversion mode for injected channels: JSWSTART
| 4 * ADC_CR2_EXTSEL_0 // External Event for regular group: TIM3TRGO
| 0 * ADC_CR2_EXTTRIG // External Trigger Conversion mode for regular channels: enabled
| 0 * ADC_CR2_JSWSTART // Start Conversion of injected channels
| 0 * ADC_CR2_SWSTART // Start Conversion of regular channels
| 0 * ADC_CR2_TSVREFE // Temperature Sensor and VREFINT disabled
;
// wait until calibration is complete
while(ADC1->CR2 & ADC_CR2_CAL)
;

ADC1->SQR1 = 0
| 0 * ADC_SQR1_SQ13_0 // 13th conversion in regular sequence channel: default
| 0 * ADC_SQR1_SQ14_0 // 14th conversion in regular sequence channel: default
| 0 * ADC_SQR1_SQ15_0 // 15th conversion in regular sequence channel: default
| 0 * ADC_SQR1_SQ16_0 // 16th conversion in regular sequence channel: default
| 0 * ADC_SQR1_L_0 // Regular channel sequence length: 1
;
ADC1->SQR3 = 0
| 0 * ADC_SQR3_SQ6_0 // 6th conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ5_0 // 5th conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ4_0 // 4th conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ3_0 // 3rd conversion in regular sequence channel: default
| 0 * ADC_SQR3_SQ2_0 // 2nd conversion in regular sequence channel: default
| 8 * ADC_SQR3_SQ1_0 // 1st conversion in regular sequence channel: ADC_IN8 (AUDIO)

ADC1->JSQR = 0
| 0 * ADC_JSQR_JSQ1_0 // 4?th conversion in injected sequence, not used
| 0 * ADC_JSQR_JSQ2_0 // 3?th conversion in injected sequence, not used
| 0 * ADC_JSQR_JSQ3_0 // 2?th conversion in injected sequence, not used
| 7 * ADC_JSQR_JSQ4_0 // 1st conversion in injected sequence, HOOK
| 0 * ADC_JSQR_JL_0 // sequence length
;
ADC1->CR1 = 0
| 7 * ADC_CR1_AWDCH_0 // Analog watchdog channel, HOOK
| 0 * ADC_CR1_EOCIE // EOC interrupt disabled
| 0 * ADC_CR1_AWDIE // Analog Watchdog interrupt disabled
| 0 * ADC_CR1_JEOCIE // Injected channels interrupt disabled
| 1 * ADC_CR1_SCAN // Scan mode, enabled (need for auto injected conversions)
| 1 * ADC_CR1_AWDSGL // watchdog on a single (AWDCH) channel
| 1 * ADC_CR1_JAUTO // injected group conversion after regular channels
| 0 * ADC_CR1_DISCEN // Discontinuous mode on regular channels, disabled.
// One pulse=one conversion
| 0 * ADC_CR1_JDISCEN // Discontinuous mode on injected channels, disabled
| 0 * ADC_CR1_DISCNUM_0 // Discontinuous mode channel count
| 1 * ADC_CR1_JAWDEN // Analog watchdog enabled on injected channels
| 0 * ADC_CR1_AWDEN // Analog watchdog disabled on regular channels
;

// start conversions
ADC1->CR2 = 0
| 1 * ADC_CR2_ADON // A/D Converter ON
| 0 * ADC_CR2_CONT // Continuous Conversion disabled
| 0 * ADC_CR2_CAL // A/D Calibration
| 0 * ADC_CR2_RSTCAL // Reset Calibration
| 1 * ADC_CR2_DMA // Direct Memory access enabled
| 1 * ADC_CR2_ALIGN // Data Alignment: left
| 7 * ADC_CR2_JEXTSEL_0 // External event for injected group: JSWSTART
| 0 * ADC_CR2_JEXTTRIG // External Trigger Conversion mode for injected channels: disabled
| 4 * ADC_CR2_EXTSEL_0 // External Event for regular group: TIM3TRGO
| 1 * ADC_CR2_EXTTRIG // External Trigger Conversion mode for regular channels: enabled
| 0 * ADC_CR2_JSWSTART // Start Conversion of injected channels
| 0 * ADC_CR2_SWSTART // Start Conversion of regular channels
| 0 * ADC_CR2_TSVREFE // Temperature Sensor and VREFINT disabled
;
Конечно, примеры не тождественны, но разницу вы увидеть должны.
QUOTE (Zol'berg @ May 8 2013, 11:42) *
Но есть другой вопрос, уже наверное не по теме : как добиться быстрой работы с портами, ассемблерные вставки?
Забудьте о них. Совсем. Прямая запись в регистры, bit-bang и DMA - ваше все. На ассемблере вы не сделаете быстрее.
Zol'berg
Спасибо за развернутый ответ, ценю!!! a14.gif
ЖесТЯЯЯЯК, я в шоке, неделю бьюсь над быстродействием, применял Bit-bang, но все равно на установку бита в порту уходило не менее 6 тактов, а на проверку состояния и прерывание - воще гора и это все при -O0 оптимизаторе, но РЕВОЛЮЦИЯ в моем осознании наступила, стоило мне переключить с -O0 на -O1, и на установку бита в порту теперь 1 такт, я об этом даже не мечтал, все вспоминал 2 такта ATMEG_и )). А как правильно организовать проверку бита в порту (в плане максимального быстродействия) ?))))). И какими средствами в CooCox или еще где, определить количества тактов на команду, можно ли сделать"виртуальный" Debug без контроллера, как в AVR-studio?
P.S. Количество тактов рассчитано примерно при помощи осцилла)))
Сергей Борщ
QUOTE (Zol'berg @ May 8 2013, 14:12) *
А как правильно организовать проверку бита в порту
Или через тот же bit-bang, или чтением GPIOx->IDR и наложением маски.
QUOTE (Zol'berg @ May 8 2013, 14:12) *
И какими средствами в CooCox или еще где, определить количества тактов на команду,
Никакими. Осциллограф вам в помощь. У него там столько наворотов в виде конвейеров, кешей, ускорителей флеши и прочего и столько условий на них влияют, что промоделировать это было бы очень и очень сложно.

QUOTE (Zol'berg @ May 8 2013, 14:12) *
можно ли сделать"виртуальный" Debug без контроллера, как в AVR-studio?
Есть несколько симуляторов. В Кейле, в ИАРе, может еще где-то. И если ядро там более-менее симулируется (и то только результат выполнения команд, но не такты), то с периферией все совсем печально. Учитывая наличие дешевых отладчиков и поддержку внутрисхемной отладки в каждом процессоре проще проверить на железе. Видимо поэтому никаких особых развитий в симуляторах не наблюдается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.