|
Непонятные ошибки при компиляции, Непонятные ошибки при компиляции |
|
|
|
May 7 2013, 20:29
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284

|
Здравствуйте, пишу значит для STMF4 в коксе, столкнулся с необъяснимыми ошибками вида "Error: offset out of range" на казалось бы совсем нормальных местах (см. скриншот и приложенный код). Возможно кто сталкивался с таким да поможет или хотя бы намекните что это может быть?
Эскизы прикрепленных изображений
|
|
|
|
|
 |
Ответов
(1 - 10)
|
May 8 2013, 06:37
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 8-05-13
Пользователь №: 76 761

|
Всем привет, я новичок на этом форуме и являюсь причиной описанного в данной теме (попросил друга выложить), сразу извиняюсь за не подготовку вопроса должным образом, а если по теме, то.. Отрабатывал инициализацию и работу в отдельных проектах SPI,DMA,GPIO,EXTILine0, по отдельности усе работает  ,если собрать до кучи SPI,DMA,GPIO, то тоже нормально работает, добавляю EXTILine0, вылетает эта ошибка, если же при этом убрать SPI, то вновь работает, и подобные заклинания в непонятной зависимости влияют на проект в целом с этой стороны. Чуть раньше было такое, когда объявления типа "GPIO_InitTypeDef GPIO_InitStructure" и "DMA_InitTypeDef DMA_InitStructure" были "вверху проекта", для всех функций (глобальные) - та же ошибка, шаманил, шаманил и перенес их в каждую функцию отдельно, в голове мысль "разницы не должно быть" и это настораживает, но факт, что помогло  . В консоли CooCox увидел "-Os" и "-flto" описанные Вами выше, но что это такое и как с этим бороться не имею и представлений, не могли бы Вы мне разъяснить, заранее спасибо  . P.S. Если нужно, в целях прозрачности понимания могу очистить проект от неиспользуемого кода и мусора и выложить)).
|
|
|
|
|
May 8 2013, 07:00
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Добро пожаловать. Для начала отключите -flto. Если поможет - обновляйте компилятор или так и оставьте с отключенной. Оптимизация свежая, все может быть. Если не поможет, читайте дальше. QUOTE (Zol'berg @ May 8 2013, 09:37)  и подобные заклинания в непонятной зависимости влияют на проект Хорошо бы посмотреть на этот ассемблерный файл. Добавьте в ключи компилятора -save-temps и найдите этот файл. QUOTE (Zol'berg @ May 8 2013, 09:37)  были "вверху проекта", для всех функций (глобальные) - та же ошибка, шаманил, шаманил и перенес их в каждую функцию отдельно, в голове мысль "разницы не должно быть" и это настораживает, но факт, что помогло  . Если вы не понимаете разницы между глобальными и автоматическими переменными, то это действительно шаманство. А авторы "примеров" к "библиотекам" ее тоже, похоже, не понимают. Их примеры - отличный образец как сделать быстрое железо медленным. QUOTE (Zol'berg @ May 8 2013, 09:37)  В консоли CooCox увидел "-Os" и "-flto" описанные Вами выше, но что это такое и как с этим бороться не имею и представлений Ройтесь по менюшкам, ищите галочки или выпадающие списки с такими или похожими названиями (-flto может называться Link-time optimization). Эти опции связаны с оптимизацией.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 8 2013, 08:08
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 8-05-13
Пользователь №: 76 761

|
Порылся в CooCox везде, по поводу -flto ничего не нашел, а вот -O0 есть, и если выбрать любые из -O1,-O2,-O3,-Os, то компилируется нормально)).
Что делать дальше, оставить как есть, -flto и -O1 ?
|
|
|
|
|
May 8 2013, 08:19
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Zol'berg @ May 8 2013, 11:08)  Что делать дальше, оставить как есть, -flto и -O1 ? А что вы хотите получить в результате? Быстрый код? Маленький код? Просто чтобы влезал в контроллер? Выбирайте. Если хотите быстрый или маленький код - избавляйтесь от "библиотек".
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 8 2013, 08:42
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 8-05-13
Пользователь №: 76 761

|
Цитата(Сергей Борщ @ May 8 2013, 10:00)  Если вы не понимаете разницы между глобальными и автоматическими переменными, то это действительно шаманство. А авторы "примеров" к "библиотекам" ее тоже, похоже, не понимают. Их примеры - отличный образец как сделать быстрое железо медленным. Глобальные и локальные переменные мне знакомы, работают по разному, но суть одна-в том, что работать должно и так и так ( и глобальные для всех функций инициализации и локальные - в каждой функции свои), а по поводу "медленных примеров", я не только/только начал изучение STM32, для меня и C нов, т.к. ранее работал с AVR на ассемблере! А как сделать быстрее, писать конфигурацию прямо в регистры? В моем проекте инициализацию можно провести медленно. Но есть другой вопрос, уже наверное не по теме : как добиться быстрой работы с портами, ассемблерные вставки? Так не могу найти описания этих самых команд для STM32F4! Может есть темы на эту тему?))
|
|
|
|
|
May 8 2013, 09:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
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 - ваше все. На ассемблере вы не сделаете быстрее.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 8 2013, 11:12
|
Участник

Группа: Участник
Сообщений: 17
Регистрация: 8-05-13
Пользователь №: 76 761

|
Спасибо за развернутый ответ, ценю!!! ЖесТЯЯЯЯК, я в шоке, неделю бьюсь над быстродействием, применял Bit-bang, но все равно на установку бита в порту уходило не менее 6 тактов, а на проверку состояния и прерывание - воще гора и это все при -O0 оптимизаторе, но РЕВОЛЮЦИЯ в моем осознании наступила, стоило мне переключить с -O0 на -O1, и на установку бита в порту теперь 1 такт, я об этом даже не мечтал, все вспоминал 2 такта ATMEG_и )). А как правильно организовать проверку бита в порту (в плане максимального быстродействия) ?))))). И какими средствами в CooCox или еще где, определить количества тактов на команду, можно ли сделать"виртуальный" Debug без контроллера, как в AVR-studio? P.S. Количество тактов рассчитано примерно при помощи осцилла)))
|
|
|
|
|
May 8 2013, 11:30
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
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? Есть несколько симуляторов. В Кейле, в ИАРе, может еще где-то. И если ядро там более-менее симулируется (и то только результат выполнения команд, но не такты), то с периферией все совсем печально. Учитывая наличие дешевых отладчиков и поддержку внутрисхемной отладки в каждом процессоре проще проверить на железе. Видимо поэтому никаких особых развитий в симуляторах не наблюдается.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|