Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Я в тупике. IAR C.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
SasaVitebsk
Проблема такая.
Прога в JTAG MK2 работает. Выключаешь/включаешь питание - нет. Точнее почти полностью работает.
Причина выяснена. Имеется одна переменная, которая объявлена в начале файла таким образом:
uint8_t static NumbActiveKom=0; // Текущее число активных команд

Эта переменная в голове инкрементируется в виде:
NumbActiveKom++; // Ввод команды завершён

А в прерывании декрементируется типа:
NumbActiveKom--; // Сократить число активных команд

Дальше я с помощью отладочного вывода выяснил, что в прерывании она уменьшается (и сохраняется от прерывания к прерыванию), а в голове увеличивается. Короче ведёт себя так, как будто это две различных переменных. Даже не совсем так. Сначала всё нормально в голове она увеличивается до 10. Потом в прерывании она должна уменьшатся и по мере уменьшения в голове должны подгружаться новые команды, а переменная должна увеличиваться. Но этого не происходит. Переменная уменьшается и в прерывании читается правильно 10,9,8,7... а в голове читается 10 на постоянку! Как будто значение переменной с прерывания не передаётся в голову.

Я попробовал остановить в JTAG прогу в нулевом адресе и "загадить" всё озу "FF". А потом запустить прогу на отладку в JTAG. Не помогает. Работает прекрасно. Как будто в JTAG своя прога, а так - своя. Пересбрасывать тоже не помогает. Надо вкл./выкл. МК. Причём на такое время, чтобы озу похезалось.

Может кто подскажет как такую хрень вычислить? Вся остальная прога работает как часы. Одна переменная только. sad.gif
GetSmart
Вообще-то такие переменные объявляются через volatile. Это чтобы компилятор не на... не обвёл вокруг пальца вобщем. Ну и если переменная находится в РАМе, то следовало бы в основной проге (не в прерывании) перед/после инкремента запрещать/разрешать прерывания.
arttab
Ескузми, а почему static? раз она меняется, то это не статик. Странно что вообще IAR не ругнулся и декремирует в прерывании
beer_warrior
Цитата
Ескузми, а почему static? раз она меняется, то это не статик. Странно что вообще IAR не ругнулся и декремирует в прерывании

Не путайте static и const.
vet
Хинт: почти все проблемы с языком программирования решаются просмотром ассемблерных листингов.
dRaider
Я тоже сталкивался с подобной лажей(точно до причины я тогда копаться не стал ) попробуй так:

еслиэто глобальная переменная лучше убрать static и обявить например
__root uint8_t NumbActiveKom=0;
компилятор не будет вмешиваться с оптимизацией.

Если не поможет увелич размер кучи и стеков (у меня после этого заработало).
_Bill
Цитата(SasaVitebsk @ Jul 7 2006, 00:46) *
Проблема такая.
Прога в JTAG MK2 работает. Выключаешь/включаешь питание - нет. Точнее почти полностью работает.
Причина выяснена. Имеется одна переменная, которая объявлена в начале файла таким образом:
uint8_t static NumbActiveKom=0; // Текущее число активных команд

Эта переменная в голове инкрементируется в виде:
NumbActiveKom++; // Ввод команды завершён

А в прерывании декрементируется типа:
NumbActiveKom--; // Сократить число активных команд

Дальше я с помощью отладочного вывода выяснил, что в прерывании она уменьшается (и сохраняется от прерывания к прерыванию), а в голове увеличивается. Короче ведёт себя так, как будто это две различных переменных. Даже не совсем так. Сначала всё нормально в голове она увеличивается до 10. Потом в прерывании она должна уменьшатся и по мере уменьшения в голове должны подгружаться новые команды, а переменная должна увеличиваться. Но этого не происходит. Переменная уменьшается и в прерывании читается правильно 10,9,8,7... а в голове читается 10 на постоянку! Как будто значение переменной с прерывания не передаётся в голову.

Код в студию!
Alex11
У IAR'а есть проблемы с оптимизатором - шибко грамотный. Иногда даже volatile к переменной не помогает (но написать его надо обязательно). Для начала в release полностью выключаешь оптимизацию - скорее всего, все заработает, дальше увеличиваешь степень оптимизации пока не сломается.
Old1
Цитата(dRaider @ Jul 7 2006, 09:45) *
Я тоже сталкивался с подобной лажей(точно до причины я тогда копаться не стал ) попробуй так:

еслиэто глобальная переменная лучше убрать static и обявить например
__root uint8_t NumbActiveKom=0;
компилятор не будет вмешиваться с оптимизацией.

Для того, чтобы компилер не вмешивался с оптимизацией, глобальную переменную нужно объявить volatile, что и рекомендовал GetSmart , а __root всего лишь "говорит" компилятору чтобы он перменную "не выкинул" даже если к ней нет обращений в коде...
IgorKossak
Цитата(Old1 @ Jul 7 2006, 10:10) *
Для того, чтобы компилер не вмешивался с оптимизацией, глобальную переменную нужно объявить volatile, что и рекомендовал GetSmart , а __root всего лишь "говорит" компилятору чтобы он перменную "не выкинул" даже если к ней нет обращений в коде...

Хотелось бы знать, какой толк в непременном наличии переменной если в программе к ней нет обращения? wink.gif
rezident
Цитата(IgorKossak @ Jul 7 2006, 13:45) *
Цитата(Old1 @ Jul 7 2006, 10:10) *

Для того, чтобы компилер не вмешивался с оптимизацией, глобальную переменную нужно объявить volatile, что и рекомендовал GetSmart , а __root всего лишь "говорит" компилятору чтобы он перменную "не выкинул" даже если к ней нет обращений в коде...

Хотелось бы знать, какой толк в непременном наличии переменной если в программе к ней нет обращения? wink.gif

А например, если нужно временно зарезервировать область в RAM, а xcl-файл править не хочется smile.gif
Сергей Борщ
Цитата(IgorKossak @ Jul 7 2006, 10:45) *
Хотелось бы знать, какой толк в непременном наличии переменной если в программе к ней нет обращения? wink.gif

Код
__root char const __flash * copyright "Слава мне, победителю драконов!"
:-))
Возможно переменнная объявляется в application а обращение к ней из bootloader section. Обе части компилятся как отдельные программы. В общем хоть и редко, но бывает надо.
IgorKossak
Цитата(Сергей Борщ @ Jul 7 2006, 12:26) *
Цитата(IgorKossak @ Jul 7 2006, 10:45) *

Хотелось бы знать, какой толк в непременном наличии переменной если в программе к ней нет обращения? wink.gif

Код
__root char const __flash * copyright "Слава мне, победителю драконов!"
:-))
Возможно переменнная объявляется в application а обращение к ней из bootloader section. Обе части компилятся как отдельные программы. В общем хоть и редко, но бывает надо.

Согласен, бывает надо.
Но в этом случае к переменной таки есть обращение в обеих частях.
Кроме того, кто может гарантировать, что в обеих частях она будет лежать в одном и том же месте если не отвести для неё отдельный сегмент в xcl файле?
rezident, ну разве что как временная мера wink.gif
SasaVitebsk
Спасибо всем за ответы, но к сожелению Вы меня не поняли. Я не перекомпилирую прогу. Тут оптимизатор ни при чём. Я беру прогу и заливаю в AVR в режиме отладки ч/з JTAG. Она прекрасно работает. Переменные видны и правильно показывают свои значения. Дальше останавливаю отладку. Выключаю и включаю питание. И эта же программа глючит описанным образом. Я её не переписываю.
Видимо что-то не инициализируется. Один раз запустилась нормально.
Меня несколько раздражает тот факт, что я JTAG брал для отладки. А с JTAG всё пашет. Запускаешь без него - ... Так нафига бабло плочено ... sad.gif
rezident
Цитата
Причина выяснена. Имеется одна переменная, которая объявлена в начале файла таким образом:
uint8_t static NumbActiveKom=0; // Текущее число активных команд

Эта переменная в голове инкрементируется в виде:
NumbActiveKom++; // Ввод команды завершён

А в прерывании декрементируется типа:
NumbActiveKom--; // Сократить число активных команд

Дальше я с помощью отладочного вывода выяснил, что в прерывании она уменьшается (и сохраняется от прерывания к прерыванию), а в голове увеличивается. Короче ведёт себя так, как будто это две различных переменных.


Если main и процедура прерывания описаны в разных Си-шных модулях, то так и будет. Переменная типа static имеет область видимости в пределах того модуля, где она описана.
Объявите ее в модуле с main-ом как

Код
volatile uint8_t NumbActiveKom=0;


а в модуле с прерыванием как

Код
extern volatile uint8_t NumbActiveKom;


и все будет инкрементировать и декрементироваться как вам хотелось.
SasaVitebsk
Цитата(rezident @ Jul 7 2006, 22:19) *
Цитата
Причина выяснена. Имеется одна переменная, которая объявлена в начале файла таким образом:
uint8_t static NumbActiveKom=0; // Текущее число активных команд

Эта переменная в голове инкрементируется в виде:
NumbActiveKom++; // Ввод команды завершён

А в прерывании декрементируется типа:
NumbActiveKom--; // Сократить число активных команд

Дальше я с помощью отладочного вывода выяснил, что в прерывании она уменьшается (и сохраняется от прерывания к прерыванию), а в голове увеличивается. Короче ведёт себя так, как будто это две различных переменных.


Если main и процедура прерывания описаны в разных Си-шных модулях, то так и будет. Переменная типа static имеет область видимости в пределах того модуля, где она описана.
Объявите ее в модуле с main-ом как

Код
volatile uint8_t NumbActiveKom=0;


а в модуле с прерыванием как

Код
extern volatile uint8_t NumbActiveKom;


и все будет инкрементировать и декрементироваться как вам хотелось.


К сожелению описаны в одном. Переменная описана вверху файла до прерывания и майн. В прерывании я её естественно не описывал. После выходных засяду поплотнее. Ну выясню конечно же. Просто, я думал, может каким то образом из под запущенной проги можно данные на JTAG передать если из под него не запускалось.
SasaVitebsk
Ошибку не нашёл. Чем бы я не забивал озу в JTAG всё работает. sad.gif

Прикол вот ещё в чём. Сделал версию "release" и напрямую зашил в кристал (ч/з AVREAL) - тоже работает. Вот и думай после этого что хочешь. sad.gif
sensor_ua
Может, просто debug-версия с точками останова, а Вы её в каменьwink.gif?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.