Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32vlDiscovery цикл for не работает
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
domowoj
STM32vlDiscovery.
Простейшая конструкция - просуммировать элементы массива.
Код
uint16_t GAME[m]={19,64,32,64,64,32,32,64,64,32,64,32,64,32,32,64,64,32,1152};
   const uint8_t m = 255;
uint16_t Tsinhro_T=0;
....
....                      
                    N = GAME[0];
                    Tsinhro_T = 0;
                    for    (i=1; i<N; i++)    
                    {                        
                    Tsinhro_T =Tsinhro_T +GAME[i];
                    }

Не хочет работать, виснет в теле цикла, причем в отладчике, пошагово,
все работает как надо.
В чем дело, мозг сломал.
Подскажите, пожалуйста, куда копать?
Xenia
Цитата(domowoj @ Mar 22 2015, 19:44) *
Подскажите, пожалуйста, куда копать?


Так писать нельзя:
uint16_t GAME[m]={19,64,32,64,64,32,32,64,64,32,64,32,64,32,32,64,64,32,1152};
Вместо [m] должна стоять константа или оставьте скобки пустыми:
uint16_t GAME[]={19,64,32,64,64,32,32,64,64,32,64,32,64,32,32,64,64,32,1152};
Сергей Борщ
Цитата(Xenia @ Mar 22 2015, 19:05) *
Так писать нельзя:
Не факт. m может быть константой, а компилятор - плюсовым, тогда такая конструкция вполне законна.
Xenia
Цитата(Сергей Борщ @ Mar 22 2015, 20:18) *
Не факт. m может быть константой, а компилятор - плюсовым, тогда такая конструкция вполне законна.


Конструкция, может быть, и законна, но едва ли m соответствует числу элементов - иначе бы цикл не зависал. sm.gif
Отсюда и мой совет оставить скобки пустыми, чтобы компилятор сам сосчитал число проинициализированных элементов.
domowoj
А почему же в отладчике работает, когда шагаешь.
Кстати, размер массива ранее определен(первый пост отредактирую) .
И еще, та же самая конструкция успешно работает в STM32F3Discovery!
Сергей Борщ
Цитата(Xenia @ Mar 22 2015, 19:42) *
Конструкция, может быть, и законна, но едва ли m соответствует числу элементов - иначе бы цикл не зависал. sm.gif
Если бы элементов было больше чем m - была бы ошибка компиляции. Если бы элементов было меньше - компилятор заполнил бы остаток массива нулями. При проходе по массиву самое страшное, что могло бы случиться - выход за пределы массива. А это привело бы либо к суммированию дополнительного мусора, либо к исключению, но не к зависанию. А поскольку в отладчике все работает - значит размер массива вычитывается из нулевой ячейки верно. В этом коде я криминала не вижу.
Интересно, а если этот цикл переместить в другое место - зависание будет снова в этом цикле? domowoj, а как определили, что зависание именно в цикле? Вообще, можно поподробнее о симптомах? Возможно неправильно настроены такты ожидания флеша и код улетает в исключение от неправильно считанного кода команды?
domowoj
Цитата(Сергей Борщ @ Mar 23 2015, 00:10) *
а как определили, что зависание именно в цикле? Вообще, можно поподробнее о симптомах?

Просто из цикла программа не выходит.
Цитата
Возможно неправильно настроены такты ожидания флеша и код улетает в исключение от неправильно считанного кода команды?
А вот это как? Я этого делать не умею, подскажите, если можно.
Xenia
Цитата(domowoj @ Mar 22 2015, 21:02) *
А почему же в отладчике работает, когда шагаешь.

Случаи, когда залезаешь в чужую память, под отладчиком часто работают нормально, потому как зависает оно обычно не тогда, когда в эту память пишется, а гораздо позже, когда выясняется, что попорчены адреса выхода из подпрограмм (стек возвратов). Увеличили бы вы размер стека - глядишь и баг бы пропал. sm.gif

Цитата(domowoj @ Mar 22 2015, 21:02) *
Кстати, размер массива ранее определен(первый пост отредактирую).

Все равно осталось неправильно, т.е. у вас m сперва используется как константа, а ее значение определяется позже.

Цитата(domowoj @ Mar 22 2015, 21:02) *
И еще, та же самая конструкция успешно работает в STM32F3Discovery!

У другого контроллера и память может быть распределена иначе.
domowoj
Цитата(Xenia @ Mar 23 2015, 00:31) *
Увеличили бы вы размер стека - глядишь и баг бы пропал. sm.gif
А как это сделать?

Xenia
Цитата(domowoj @ Mar 22 2015, 21:40) *
А как это сделать?


У IAR'а это в Option.
domowoj
А в Keil?
Xenia
Цитата(domowoj @ Mar 22 2015, 21:58) *
А в Keil?


А Keil я не понимаю. sm.gif
Golikov A.
там же, в прожект пропертисях...
только надо не стэк увеличивать, а понять где он ломается...

вам надо сделать обработчик прерывания Hard fault и поглядеть не в нем ли вы оказываетесь, а дальше есть методы поиска почему туда попали...

Код
Tsinhro_T = 0;


это че за хрень? без типа? описание типа какое?
mantech
Цитата(Golikov A. @ Mar 22 2015, 22:04) *
только надо не стэк увеличивать, а понять где он ломается...


Не знаю, что такого в этой процедуре, что может стек поломать...

Отключите оптимизацию, и воткните в тело цикла что-то вроде printf("I=%d\n",i); И посмотрите, на каком шаге виснет...

Цитата(Xenia @ Mar 22 2015, 21:31) *
Все равно осталось неправильно, т.е. у вас m сперва используется как константа, а ее значение определяется позже.


И это тоже согласен.
zhevak
Цитата(domowoj @ Mar 22 2015, 22:44) *
Не хочет работать, виснет в теле цикла, причем в отладчике, пошагово,
все работает как надо.


Вы можете поставть две точки останова: одну до цикла, вторую после цикла?

1. И когда, по вашему представлению, программа зависнет на выполнении цикла, остановть ее (нажать "паузу" или что-то там в Кайле нажимают) и посмотреть на переменную цикла и на сумму.

2. Попрбуйте поиграть с количество итераций цикла. Задайте в цикле просумировать один элент. Два элемента. Пять элементов... Просто попробуйте набрать статистику зависаний.

3. Кроме этого цикла, программа какие еще действия делает? Особенно интересуют какие прерывания Вы используете. Я к чему это говорю -- к тому, что возможно во время работы (конкретно -- во время выполнения этого злополучного цикла) возникает прерывание и оно как-нибудь не правильно обрабатывается. например, тупо не снимается флаг прерывания, который должен сниаться программно. Я не знаю, никто не знает что там у Вас происходит. Но наиболее вероятные версии нужно отработать -- проверить. Всё равно что-то делать надо.

4. Что еще могу предложить -- если есть осциллограф, то предлагаю вписать в тело цикла команду дергания какой-нибудь свободной ножки проца. и осциллографом попробовать уловить сколько итераций совершает цикл. Может быть он лупит бесконечность, а модет слелает пару-тройку и процесс уходит в обработку какого-нибудь прерывания.
Golikov A.
Цитата
Не знаю, что такого в этой процедуре, что может стек поломать...

да нет там ничего, 3 строчки, все просто...

ТС почему то упорно скрывает от нас реальный код, и дает какие-то выжимки. Тем самым от нас скрыта правда, а видно только то что автор считаем важным, при этом поскольку у автора ошибка, очевидно автор не очень осознает что же на самом деле важно, а что нет)...

Если только Tsinhro_T - ни какой-то злобный тип для которого перегружен оператор присвоения как-то очень злобно...

что с вочь догом, с задержкой чтения флеши, с другими прерываниями?

самое простое запретить все прерывания, и поглядеть если через цикл пройдет, то точно дело в них...

domowoj
Ладно, спасибо за наводки, буду пробовать,
потом отпишусь.
domowoj
Добрый вечер уважаемые друзья!
Цитата(Golikov A. @ Mar 23 2015, 01:41) *
ТС почему то упорно скрывает от нас реальный код, и дает какие-то выжимки.
Тем самым от нас скрыта правда,
а видно только то что автор считаем важным, при этом поскольку у автора ошибка,
очевидно автор не очень осознает что же на самом деле важно, а что нет)...

Вы оказались абсолютно правы.
После таймаута, (взгляд все-таки замыливается) и внимательного разбора написанного,
нашел ЛЯП, как AVR_овский отголосок,
при сбросе флага одного из прерываний я его не сбрасывал в 0, а устанавливал в "1".
Вместо
Код
    TIM4->SR &= ~TIM_SR_UIF; //

было
Код
    TIM4->SR |=  TIM_SR_UIF; //


Спасибо всем, тема закрыта.
Golikov A.
Стойте стойте... Давайте пока она не совсем закрыта еще кое что скажем...

В АРМах не принято сбрасывать флаги прерываний через &=, это несет в себе потенциальную опасность сбросить прерывание которое наступило пока вы сбрасываете прерывание...

обычно все такие флаговые регистры чувствительны только к записи одного уровня, то есть обычно надо записать в регистр значение через = с помеченным для сброса флагом, а всем остальными стоящими в обратном значении.... это сбросит только помеченные флаги и не изменит остальные.... Обратите на это внимание...

на пальцах
&= - это не атомарная операция, это
взять регистр
изменить регистр
записать регистр
между этими командами может придти еще прерывание, и вы его случайно затрете этими действиями...
etoja
Напишите
volatile int i;

чтобы компилятор не кешировал переменную в регистр процессора.
Golikov A.
Если это ответ мне, то это не поможет....
Если не понимаете почему, то надо читать что я написал и думать...
Если не мне, то к чему это?

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.