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

 
 
> Я в тупике. 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
 
Start new topic
Ответов
dRaider
сообщение Jul 7 2006, 06:45
Сообщение #2


Участник
*

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



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

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

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


Знающий
****

Группа: Свой
Сообщений: 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
Сообщение #4


Шаман
******

Группа: Модераторы
Сообщений: 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
Сергей Борщ
сообщение Jul 7 2006, 09:26
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 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
Сообщение #6


Шаман
******

Группа: Модераторы
Сообщений: 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
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 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
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 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
SasaVitebsk
сообщение Jul 7 2006, 22:48
Сообщение #9


Гуру
******

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



Цитата(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 передать если из под него не запускалось.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- SasaVitebsk   Я в тупике. IAR C.   Jul 6 2006, 21:46
- - GetSmart   Вообще-то такие переменные объявляются через volat...   Jul 6 2006, 23:19
- - arttab   Ескузми, а почему static? раз она меняется, то это...   Jul 7 2006, 01:18
- - beer_warrior   ЦитатаЕскузми, а почему static? раз она меняется, ...   Jul 7 2006, 06:02
- - vet   Хинт: почти все проблемы с языком программирования...   Jul 7 2006, 06:13
|- - rezident   Цитата(IgorKossak @ Jul 7 2006, 13:45) Ци...   Jul 7 2006, 09:05
- - _Bill   Цитата(SasaVitebsk @ Jul 7 2006, 00:46) П...   Jul 7 2006, 06:58
- - Alex11   У IAR'а есть проблемы с оптимизатором - шибко ...   Jul 7 2006, 07:06
- - SasaVitebsk   Ошибку не нашёл. Чем бы я не забивал озу в JTAG вс...   Jul 8 2006, 18:01
- - sensor_ua   Может, просто debug-версия с точками останова, а В...   Jul 8 2006, 21:25


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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 07:30
Рейтинг@Mail.ru


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