ierofant 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 (изменено) · Жалоба Всем привет. Возникла странная проблема с которой я не могу разобратся. Контроллер - STM32F100RB. Компилятор - IAR for ARM 6.21 Есть обьявление глобальных переменных: uint16_t b[50]; //тест uint16_t b1[50]; //тест unsigned char time_to_break=0; unsigned int counter=0; unsigned char ban=0; unsigned char push_button=0; .... еще несколько переменных .... unsigned char test[100]; В этом случае еще до входа в главную функцию массив test заполнен символами "я". Если записать к примеру unsigned char test[]="hello my sweety"; , то остальные переменные будут содержать неверные и произвольные значения + контроллер зависает в B HardFault_Handler. Если обьявление массивов b1 и b2 разместить после обьявления всех остальных переменных, то будет та же ситуация. - неверные значения остальных переменных и зависание B HardFault_Handler. В общем от перестановки местами строчек обьявления переменных конечная работа устройства очень меняется и в большинстве случаев имеет какую-то проблему. У меня есть подозрения, что из-за различности типов (char, uint) или еще из-за чего-то происходит неправильное размещение переменных в оперативной памяти. (и они как-то накладываются) Если это так, то как решается? Если нет: Подскажите, в чем проблема и как с ней бороться. Буду очень признателен. Заранее благодарен за помощь. Изменено 11 ноября, 2011 пользователем ierofant Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба У меня есть подозрения, что из-за различности типов (char, uint) или еще из-за чего-то происходит неправильное размещение переменных в оперативной памяти. (и они как-то накладываются) Если это так, то как решается?Нет, это не так. Исходите из того, что компилятор вас не обманывает. Сколько ОЗУ у вас занято под переменные? Сколько памяти выделено под стеки? Эти переменные глобальные или локальные? Симптомы указывают на нехватку стека - стек налезает на переменные. И надо смотреть- если есть куда, то увеличивать стек. Если некуда - урезать осетра, т.е. оптимизировать программу, избавляясь от лишних переменных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 (изменено) · Жалоба В этом случае еще до входа в главную функцию массив test заполнен символами "я". До входа в главную функцию (main) выполняется загрузчик, который и заполняет инициализировнные в коде переменные их значениями, а остальные нулями. Вообще похоже на неверный скрипт линкера и/или загрузчик. Один раз был похожий косяк, правда с gcc: в зависимости от размеров переменных или даже перетаскивания их по коду программа работал или валилась в Hard Fault, уже грешил на компилятор. В итоге оказалось что вектора прерывания сремапленные в оперативку были выровнены по неверному значению (0x100, а надо было по 0x400) Старый код работал на stmf100, где прерываний меньше и выравнивания 0x100 было достаточно, при переносе на stm32f2 используемых прерываний оказалось больше и некоторые не срабатывали. Изменено 11 ноября, 2011 пользователем Flexz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ierofant 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Нет, это не так. Исходите из того, что компилятор вас не обманывает. Сколько ОЗУ у вас занято под переменные? Сколько памяти выделено под стеки? Эти переменные глобальные или локальные? Симптомы указывают на нехватку стека - стек налезает на переменные. И надо смотреть- если есть куда, то увеличивать стек. Если некуда - урезать осетра, т.е. оптимизировать программу, избавляясь от лишних переменных. Если считать с массивами - до 1кБ занято переменными. Под стеки было выделенно 1кБ, я увеличил это значение до 3кБ - ничего не изменилось все те же лишние значения в переменных и HardFault. Кучу на всякий тоже до 3 кБ увеличил - никакого эффекта. Все переменные глобальные. По тексту программы есть и локальные, но уже до их обьявления и инициализации уже появляются какие-то проблемы. До входа в главную функцию (main) выполняется загрузчик, который и заполняет инициализировнные в коде переменные их значениями, а остальные нулями. Вообще похоже на неверный скрипт линкера и/или загрузчик. Один раз был похожий косяк, правда с gcc: в зависимости от размеров переменных или даже перетаскивания их по коду программа работал или валилась в Hard Fault, уже грешил на компилятор. В итоге оказалось что вектора прерывания сремапленные в оперативку были выровнены по неверному значению (0x100, а надо было по 0x400) Старый код работал на stmf100, где прерываний меньше и выравнивания 0x100 было достаточно, при переносе на stm32f2 используемых прерываний оказалось больше и некоторые не срабатывали. Симптомы очень похожи. Могли бы вы немного подробнее описать, как это проверить, как узнать что должно быть и какие значения сейчас у меня? А то я раньше в таких дебрях еще не копался.) Открыл новую зависимость : Если обьявляется 2 массива : uint16_t b[50]; uint16_t b1[50]; То начинаются такие проблемы. Если же обьявлять только один массив - все ок: uint16_t b[1000]; //uint16_t b1[50]; Можно что угодно местами переставлять и не будет проблем. Причем величину этого массива можно установить хоть 1000 элементов, все отлично работает. Вообще не понятно, какая разница в обьявлении двух массивов по 50 или одного на 100 элементов? Почему так коряво работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Почему так коряво работает?Давайте посмотрим .map Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Ну поскольку у вас IAR то скорее всего стартап и скрипт линкера правильные (если, конечно, вы их не меняли руками), предположение об их корявости скорее относится к GCC, там каждый их или подбирает готовые на просторах инета или пишет свои. Действительно надо map смотреть. PS а процессором в настройках не ошиблись? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ierofant 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Нашел ошибку. Была она в некорректном применении созданых тестовых массивов. Инициализировал так : uint16_t b[50]; uint16_t b1[50]; А так обрабатывались( i<99): for(int i=0; i<99; i++) {b[i]= *p1; p1++;} Значение 99 перекочевало с предыдущей функции, когда использовался 100 элементный массив. Исправил на 49 - все работает нормально. А в .map все нормально, потому и начал искать в других местах промах. Ошибка глупая такая, стыдно. Кстати, нигде не предусмотренна защита от превышения количества обьявленных элементов массива? Всем большое спасибо за участие и помощь! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Allregia 9 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Кстати, нигде не предусмотренна защита от превышения количества обьявленных элементов массива? Обычно она "предусморена" в голове прогграммиста, который вместо: uint16_t b[50]; uint16_t b1[50]; for(int i=0; i<99; i++) {b[i]= *p1; p1++;} пишет так: #define ARRAY_SIZE 50 uint16_t b[ARRAY_SIZE]; uint16_t b1[ARRAY_SIZE]; for(int i=0; i<ARRAY_SIZE-1; i++) {b[i]= *p1; p1++;} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба #define ARRAY_SIZE 50 for(unsigned int i=0; i<sizeof(b)/sizeof(b[0]); i++) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ierofant 0 11 ноября, 2011 Опубликовано 11 ноября, 2011 · Жалоба Allregia, Сергей Борщ спасибо за полезные паттерны, буду использовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 14 ноября, 2011 Опубликовано 14 ноября, 2011 · Жалоба HardFault - это кстати и есть такая защита. Процессор вообще-то мог бы молча записать по заданным адресам и ничего не сказать. Вот тогда бы намучались вы в поисках ошибки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться