реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Я в тупике. IAR C., может кто подскажет ниточку ...
SasaVitebsk
сообщение Jul 6 2006, 21:46
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Проблема такая.
Прога в JTAG MK2 работает. Выключаешь/включаешь питание - нет. Точнее почти полностью работает.
Причина выяснена. Имеется одна переменная, которая объявлена в начале файла таким образом:
uint8_t static NumbActiveKom=0; // Текущее число активных команд

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

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

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

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

Может кто подскажет как такую хрень вычислить? Вся остальная прога работает как часы. Одна переменная только. sad.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jul 6 2006, 23:19
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Вообще-то такие переменные объявляются через volatile. Это чтобы компилятор не на... не обвёл вокруг пальца вобщем. Ну и если переменная находится в РАМе, то следовало бы в основной проге (не в прерывании) перед/после инкремента запрещать/разрешать прерывания.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
arttab
сообщение Jul 7 2006, 01:18
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



Ескузми, а почему static? раз она меняется, то это не статик. Странно что вообще IAR не ругнулся и декремирует в прерывании


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Jul 7 2006, 06:02
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
Ескузми, а почему static? раз она меняется, то это не статик. Странно что вообще IAR не ругнулся и декремирует в прерывании

Не путайте static и const.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
vet
сообщение Jul 7 2006, 06:13
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Хинт: почти все проблемы с языком программирования решаются просмотром ассемблерных листингов.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
dRaider
сообщение Jul 7 2006, 06:45
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 15
Регистрация: 26-08-05
Пользователь №: 7 991



Я тоже сталкивался с подобной лажей(точно до причины я тогда копаться не стал ) попробуй так:

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

Если не поможет увелич размер кучи и стеков (у меня после этого заработало).
Go to the top of the page
 
+Quote Post
_Bill
сообщение Jul 7 2006, 06:58
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



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

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

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

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

Код в студию!
Go to the top of the page
 
+Quote Post
Alex11
сообщение Jul 7 2006, 07:06
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 106
Регистрация: 23-10-04
Из: С-Петербург
Пользователь №: 965



У IAR'а есть проблемы с оптимизатором - шибко грамотный. Иногда даже volatile к переменной не помогает (но написать его надо обязательно). Для начала в release полностью выключаешь оптимизацию - скорее всего, все заработает, дальше увеличиваешь степень оптимизации пока не сломается.
Go to the top of the page
 
+Quote Post
Old1
сообщение Jul 7 2006, 07:10
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095



Цитата(dRaider @ Jul 7 2006, 09:45) *
Я тоже сталкивался с подобной лажей(точно до причины я тогда копаться не стал ) попробуй так:

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

Для того, чтобы компилер не вмешивался с оптимизацией, глобальную переменную нужно объявить volatile, что и рекомендовал GetSmart , а __root всего лишь "говорит" компилятору чтобы он перменную "не выкинул" даже если к ней нет обращений в коде...
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jul 7 2006, 07:45
Сообщение #10


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



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

Хотелось бы знать, какой толк в непременном наличии переменной если в программе к ней нет обращения? wink.gif
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 7 2006, 09:05
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(IgorKossak @ Jul 7 2006, 13:45) *
Цитата(Old1 @ Jul 7 2006, 10:10) *

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

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

А например, если нужно временно зарезервировать область в RAM, а xcl-файл править не хочется smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 7 2006, 09:26
Сообщение #12


Гуру
******

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



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

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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jul 7 2006, 12:30
Сообщение #13


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Сергей Борщ @ 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
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 7 2006, 18:36
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Спасибо всем за ответы, но к сожелению Вы меня не поняли. Я не перекомпилирую прогу. Тут оптимизатор ни при чём. Я беру прогу и заливаю в AVR в режиме отладки ч/з JTAG. Она прекрасно работает. Переменные видны и правильно показывают свои значения. Дальше останавливаю отладку. Выключаю и включаю питание. И эта же программа глючит описанным образом. Я её не переписываю.
Видимо что-то не инициализируется. Один раз запустилась нормально.
Меня несколько раздражает тот факт, что я JTAG брал для отладки. А с JTAG всё пашет. Запускаешь без него - ... Так нафига бабло плочено ... sad.gif
Go to the top of the page
 
+Quote Post
rezident
сообщение Jul 7 2006, 19:19
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата
Причина выяснена. Имеется одна переменная, которая объявлена в начале файла таким образом:
uint8_t static NumbActiveKom=0; // Текущее число активных команд

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

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

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


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

Код
volatile uint8_t NumbActiveKom=0;


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

Код
extern volatile uint8_t NumbActiveKom;


и все будет инкрементировать и декрементироваться как вам хотелось.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 16:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.01482 секунд с 7
ELECTRONIX ©2004-2016