|
|
  |
Ключевое слово "Volatile" |
|
|
|
Nov 16 2015, 08:25
|
Группа: Новичок
Сообщений: 4
Регистрация: 13-11-15
Из: Санкт-Петербург
Пользователь №: 89 305

|
Доброго времени суток. Написал программу в CodeVisionAVR, смотрю изменение значений переменных в Протеусе. Переменные, за которыми я слежу, являлись типом "long int". В какой-то момент я решил сделать их просто int, т.к. значения в проге вполне вписываются и без приставки long. Внезапно в протеусе появляется такая надпись на месте значения переменной - Item (2 bytes at 0xFFFF0504) not within memory block (0x00000460 bytes), и изменилась запись адреса - R-64252:R64251 . При этом программа работает нормально, просто не получается следить за значениями переменных. Вот скриншот. http://i.imgur.com/0WM63lR.jpg ([img] почему-то не работает, приходится оставлять в виде ссылки) Погуглив, я нашёл решение данной проблемы - добавить ключевое слово Volatile перед int. Это помогло, но мне хотелось бы разобраться до конца : - Что означает запись на месте значения переменной?
- Почему этой проблемы не было с long int?
- Что делает слово Volatile в данном случае?
- Ну и как бонусный вопрос, есть ли способ выводить значения переменных типа float? (у меня это D, U, Uprop ...)
Буду благодарен за помощь.
Сообщение отредактировал RollForRepair - Nov 16 2015, 08:26
|
|
|
|
|
Nov 16 2015, 09:27
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 31-03-14
Из: Харьков
Пользователь №: 81 165

|
вероятнее всего переменная не отображалась в протеусе, т.к. CVAvr ее оптимизировал (убил за ненадобностью) в том месте, где вы ее пытались смотреть. volatile сказал компилятору, что нужно оптимизировать осторожнее  100 раз подумайте, перед тем, как использовать в AVR переменные типа float - огромное потребление ресурсов.
|
|
|
|
|
Nov 16 2015, 09:28
|

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

|
Цитата(RollForRepair @ Nov 16 2015, 11:25)  Погуглив, я нашёл решение данной проблемы - добавить ключевое слово Volatile перед int. Это лечение симптомов, а не причины. volatile существует для другого. В данном случае оно сделало вашу маленькую быструю программу больше и медленнее. Цитата(RollForRepair @ Nov 16 2015, 11:25)  Что означает запись на месте значения переменной? Никогда не работал с вашим компилятором, но смею предположить, что это означает, что ваша переменная хранится в регистрах, а не в ОЗУ. Поэтому отладчик не может ее отобразить. Убедиться в этом можно, рассмотрев внимательно дизасемблерный код в местах обращения к этой переменной. Цитата(RollForRepair @ Nov 16 2015, 11:25)  Почему этой проблемы не было с long int? Если первое предположение верно, то раньше эта переменная в регистры не помещалась и компилятор был вынужден разместить ее в ОЗУ. Цитата(RollForRepair @ Nov 16 2015, 11:25)  Что делает слово Volatile в данном случае? То же, что и в любом другом случае - говорит компилятору, что значение переменной может измениться в любой момент неизвестным ему образом и что любая запись в эту переменную влияет на "наблюдаемое поведение" программы. Это запрещает оптимизацию обращений к переменной. С этим ключевым словом компилятор обязан выполнить любое действие с этой перемееной именно так и в том порядке, в котором оно описано в программе. Если вы написали a = 1; a++; то компилятор обязан сначала записать в переменную 1, потом прочитать из этой переменной ее содержимое, увеличить его на 1 и записать результат обратно. Он уже не имеет права соптимизировать эти действия и записать в переменную a сразу значение 2, потому что volatile говорит, что во-первых между a=1 и a++ значение a могло измениться (например, если это отраженный на память регистр ввода или между этими действиями произошло прерывание, обработчик которого изменил переменную) и что обе записи могли на что-то влиять (опять же, если это отраженный на память регистр вывода или же между этими выражениями произошло прерывание, которое должно было считать из a первое значение) Цитата(RollForRepair @ Nov 16 2015, 11:25)  Ну и как бонусный вопрос, есть ли способ выводить значения переменных типа float? Это надо искать в документации или спрашивать у службы техподдержки вашего компилятора и отладчика. Вы ведь их честно купили?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 16 2015, 10:34
|
Группа: Новичок
Сообщений: 4
Регистрация: 13-11-15
Из: Санкт-Петербург
Пользователь №: 89 305

|
Цитата(Сергей Борщ @ Nov 16 2015, 12:28)  ... Большое спасибо за подробный ответ! Цитата(slavokhire5 @ Nov 16 2015, 12:27)  ...100 раз подумайте, перед тем, как использовать в AVR переменные типа float - огромное потребление ресурсов. А какой тип данных мне использовать, если целочисленным не обойтись? (Мне надо умножить разность целочисленных переменных на коэффициент от 0 до 1, то есть результат будет нецелочисленный)
|
|
|
|
|
Nov 17 2015, 13:01
|
Группа: Новичок
Сообщений: 4
Регистрация: 13-11-15
Из: Санкт-Петербург
Пользователь №: 89 305

|
Цитата(sigmaN @ Nov 17 2015, 03:16)  А тут недавно, в соседней ветке, мне вполне аргументированно объяснили, что ежели по быстродействию и объему памяти с плавучкой всё работает, то есть ли смысл мучить себя Fixed point? И вы знаете, я вынужден был согласиться, хотя и тоже являюсь ярым противником использования float на любых процах без FPU, а уж тем более на AVR. Так что не заморачивайте новичку голову. Лучше уговорите его слезть пораньше с CodeVisionAVR  Ну, я уже начитался плохого про диалектные фишки CVAVR - мол, запись " PORTB.7 = 1; " не сработает на других компиляторах. На что посоветуете перейти? Сейчас я тренируюсь на Atmega8, однако рано или поздно надо будет переходить на PIC, связано с работой. Я думал о переходе на AVR Studio.
|
|
|
|
|
Nov 17 2015, 14:43
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(sigmaN @ Nov 17 2015, 03:16)  А тут недавно, в соседней ветке, мне вполне аргументированно объяснили, что ежели по быстродействию и объему памяти с плавучкой всё работает, то есть ли смысл мучить себя Fixed point? И вы знаете, я вынужден был согласиться, хотя и тоже являюсь ярым противником использования float на любых процах без FPU, а уж тем более на AVR. Так что не заморачивайте новичку голову. Лучше уговорите его слезть пораньше с CodeVisionAVR  поддержу. 1. выдираем плавучую часть алгоритма. 2. запускаем симулятор 3. энджой. Цитата(RollForRepair @ Nov 17 2015, 16:01)  Ну, я уже начитался плохого про диалектные фишки CVAVR - мол, запись " PORTB.7 = 1; " не сработает на других компиляторах. На что посоветуете перейти? Сейчас я тренируюсь на Atmega8, однако рано или поздно надо будет переходить на PIC, связано с работой. Я думал о переходе на AVR Studio. можете не блуждать в поисках а написать "диалектную" прокладку, - выделить для себя любимое подмножество фич и добиться его работы на разных компиляторах и разных архитектурах: CV, IAR, GCC, (xc8/16 раз уж на пиках потом будете) и ничего страшного, если более элегантное PORTB.7 = 1; заменится на горбатенькое, но рабочее и переносимое #define set_bit(port,bit,value) тратата
Сообщение отредактировал _Pasha - Nov 17 2015, 14:46
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|