Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 31.01.2014, 16:00  
SasaVitebsk
Гражданин KAZUS.RU
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

Godzilla82 Вы меня не поняли. Я писал все переменные в памяти.
В первом листинге переменные находятся в регистрах.
Установите галочку чтобы компилятор располагал переменные в памяти и дайте, пожалуйста распечатку без volatile. Нужен только без volatile. Остальное я уже увидел.
Заранее благодарю.
Реклама:
SasaVitebsk вне форума  
Непрочитано 31.01.2014, 16:07  
Godzilla82
Почётный гражданин KAZUS.RU
 
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
Godzilla82 на пути к лучшему
Сообщение Re: CodeVisionAVR 2.60

int a,b,c,d:
Автоматически располагать переменные в регистрах - выключено

Код:
;for(;;)
_0x4:
;{
;if(a == 100)    PINA |= 1;
	LDS  R26,_a
	LDS  R27,_a+1
	CPI  R26,LOW(0x64)
	LDI  R30,HIGH(0x64)
	CPC  R27,R30
	BRNE _0x6
	SBI  0x19,0
;b = 2000;
_0x6:
	LDI  R30,LOW(2000)
	LDI  R31,HIGH(2000)
	STS  _b,R30
	STS  _b+1,R31
;b += PINA;
	IN   R30,0x19
	LDS  R26,_b
	LDS  R27,_b+1
	LDI  R31,0
	ADD  R30,R26
	ADC  R31,R27
	STS  _b,R30
	STS  _b+1,R31
;for(i=0; i‹200; i++)    {
	LDI  R17,LOW(0)
_0x8:
	CPI  R17,200
	BRSH _0x9
;if(b › TCNT1)   {
	IN   R30,0x2C
	IN   R31,0x2C+1
	LDS  R26,_b
	LDS  R27,_b+1
	CP   R30,R26
	CPC  R31,R27
	BRSH _0xA
;PINA |= 2;
	SBI  0x19,1
;break;
	RJMP _0x9
;}
;}
_0xA:
	SUBI R17,-1
	RJMP _0x8
_0x9:
;if(c == 75)     PINA |= 4;
	LDS  R26,_c
	LDS  R27,_c+1
	CPI  R26,LOW(0x4B)
	LDI  R30,HIGH(0x4B)
	CPC  R27,R30
	BRNE _0xB
	SBI  0x19,2
;if(d == 1)      PINA |= 8;
_0xB:
	LDS  R26,_d
	LDS  R27,_d+1
	SBIW R26,1
	BRNE _0xC
	SBI  0x19,3
;}
_0xC:
	RJMP _0x4
Godzilla82 вне форума  
Непрочитано 31.01.2014, 16:46  
SasaVitebsk
Гражданин KAZUS.RU
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

Ну что я скажу ... Из того, что я вижу - вы правы. Действительно смысла в volatile в CV нет никакого, при таком коддинге. (( Это максимальная оптимизация? Или я, применительно к CV, глупость спросил?

Ваши рассказы о том, что он угадывает мои желания, мягко говоря, не совсем соответствуют тому, что я вижу.
Например:
Код:
;b = 2000;
_0x6:
	LDI  R30,LOW(2000)
	LDI  R31,HIGH(2000)
	STS  _b,R30             ; Он неугадал. Согласно исходного текста, я об этом не просил.
	STS  _b+1,R31
;b += PINA;
	IN   R30,0x19
	LDS  R26,_b             ; соответственно полная бессмыслица.
	LDS  R27,_b+1
	LDI  R31,0
	ADD  R30,R26
	ADC  R31,R27
	STS  _b,R30
	STS  _b+1,R31
Итого в двух сишных операторах получаем +8 тактов +16 байт оверхеда.
IAR этот оверхед включит, только при условии volatile.

То есть по сути - вы правы, только я не понимаю смысла вашей радости. Это соответствует моему видению ситуации или глобальная неэффективность или применение volatile обязательно. CV выбрал первое.

Теперь про угадывание.
Не должно быть никакого угадывания. Вы должны донести компилятору, свою идею. Именно для этой цели создан язык программирования. Все элементы языка нацелены на то, чтобы передать компилятору смысл того, что я хочу сделать. Чем ниже уровень языка, тем выше эффективность результирующего кода, но при этом больше конструкций детализирующих задачу. Язык Си - язык среднего уровня. Поэтому детализаций много. Это не плохо и не хорошо. Это данность. Хотите более высокоуровневый язык - пожалуйста пользуйтесь им. Насколько мне не изменяет склероз, в Basic вообще нет разделения на int и float. По крайней мере в первоначальных версиях было так. Это для примера.

Поймите. Речь ведь не всегда идёт о программе из 10 строчек. А если у меня 70 тыс строк и порядка 600 файлов? А если приложение обращается к переменной в бутлоадере, которой вообще нет в проекте? А если я использую шаблоны конфигурирования или сценарии написанные на скриптах и потом компилирую, или некоторые модули написаны на другом языке программирования? Компилятор не может охватить весь ваш замысел и согласно стандарту языка, не должен это делать! Согласно стандарту, каждая процедура является самостоятельной единицей, не связанной с другой. Компилятор не следит за проектом! Объединение в результирующий проект осуществляет линкер. Компилятор не может знать что и в каком потоке выполняется. Может у вас 2 ядра. 1 процедура выполняется в одном - другая в другом. Или 32 как в пропеллере. Таким образом компилятор не знает как ведёт себя глобальная переменная! Требуется дополнительное указание. И страшного тут ничего нет, в рамках данного языка.

Надеюсь я объяснил понятно.
SasaVitebsk вне форума  
Непрочитано 31.01.2014, 20:51  
Godzilla82
Почётный гражданин KAZUS.RU
 
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
Godzilla82 на пути к лучшему
Сообщение Re: CodeVisionAVR 2.60

Сообщение от SasaVitebsk Посмотреть сообщение
Например:
[CODE];b = 2000;
_0x6:
LDI R30,LOW(2000)
LDI R31,HIGH(2000)
STS _b,R30 ; Он неугадал. Согласно исходного текста, я
об этом не просил.
STS _b+1,R31
Почему не просил? Вы в исходном тексте присвоили переменной b значение 2000. Что он и сделал. Переменная в памяти? Вот он в памяти и поменял значение.

Сообщение от SasaVitebsk Посмотреть сообщение
Код:
;b += PINA;
	IN   R30,0x19
	LDS  R26,_b             ; соответственно полная бессмыслица.
	LDS  R27,_b+1
	LDI  R31,0
	ADD  R30,R26
	ADC  R31,R27
	STS  _b,R30
	STS  _b+1,R31
Почему бессмыслица? Он действует согласно указаниям. Да, не оптимально. Но действует правильно. Согласно тому, что написнао в коде Си.
Godzilla82 вне форума  
Непрочитано 01.02.2014, 01:14  
tempora
Почётный гражданин KAZUS.RU
 
Регистрация: 10.01.2007
Сообщений: 3,412
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
tempora на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

Сообщение от olc0267 Посмотреть сообщение
Дело не в printf. tempora намекал, что sizeof() в CV работает некорректно.
Поздравляю, это правильный ответ.

Сообщение от olc0267 Посмотреть сообщение
Но, судя по тому, что у Вас всё заработало нормально в версии 2.0.3, то баг этот уже несколько лет как пофиксен.
Он был пофиксен даже раньше, но в CV "место багов пусто не бывает" - на смену этому пришло несколько новых.

Сообщение от olc0267 Посмотреть сообщение
tempora ведь не говорит, какая у него версия CV. Или говорил где-то?
Дело не в номере версии, а в том, что (цитирую оттуда же):
Сообщение от tempora Посмотреть сообщение
Вспоминать все глюки CvAvr нет ни желания, ни возможности (поисковики - в помощь), но их более чем достаточно, чтобы перестать признавать в нем компилятор.
Да еще состав этих глюков с каждой новой версией меняется - это уж и вовсе "для настоящих джигитов".

Сообщение от olc0267 Посмотреть сообщение
Интересно, какой объём памяти занимает такая конструкция - sizeof(xlattable)/sizeof(*xlattable)? Что хорошо в ПК, не всегда хорошо в МК. Я бы не поленился конкретно в этом случае константу вбить, и фиг с ней, с универсальностью кода.
Никакого объёма sizeof не занимает, так как вычисляется на этапе компиляции, а в коде присутствует именно константа, которую хотели вставить вы. Так что, "фиг с ней, с универсальностью кода" - это плохой ход.

Сообщение от SasaVitebsk Посмотреть сообщение
Согласно стандарту, каждая процедура является самостоятельной единицей, не связанной с другой. Компилятор не следит за проектом!
Мало того, если он и попытается это сделать, ему это не поможет, так как:
1. содержимого библиотек он не видит и не знает, что там будет происходить,
2. существуют такие переменные, которые меняются вовсе не программой - тут даже точное знание действий, выполняемых в библиотеке не поможет,
3. существуют порты ввода/вывода, содержимое которых и вовсе меняется откуда-то снаружи контроллера.
__________________
There's always more than one way to skin a cat.
tempora вне форума  
Непрочитано 01.02.2014, 10:31  
olc0267
Почётный гражданин KAZUS.RU
 
Регистрация: 06.08.2008
Адрес: Ярославль
Сообщений: 1,505
Сказал спасибо: 115
Сказали Спасибо 1,314 раз(а) в 548 сообщении(ях)
olc0267 на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

Цитата:
Надеюсь я объяснил понятно.
Да мне не нужно это объяснять, я не вчера родился. Вы говорите об общих вещах, а я - о частных случаях.
А в частных случаях:
1. volatile инструктирует компилятор не предпринимать никаких оптимизаций к переменной. В случае программирования AVR - перечислите по пальцам, что может сделать компилятор с глобальной переменной, кроме размещения в регистре?
Имхо, конкретно в этом случае, во всех компиляторах всё перевёрнуто с ног на голову. По умолчанию не нужно пихать глобальные переменные в регистры. Если программисту понадобится, он может объявить переменную как register. В CV есть такая возможность - всё запретить, а разрешать по мере надобности.
2.
Код:
void del ( int volatile a)
{
	while (a) --a;
}
С точки зрения стандарта языка здесь нет ошибки. Но один компилятор совсем выкинул этот код, а другой более уважительно отнёсся к программисту. Если человек написал - значит, ему так надо. И он попытался сделать всё от него зависящее, причём более грамотно, чем тот другой компилятор. Чем и заслужил моё ответное уважение.

Последний раз редактировалось olc0267; 01.02.2014 в 19:16.
olc0267 вне форума  
Непрочитано 01.02.2014, 19:27  
SasaVitebsk
Гражданин KAZUS.RU
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

Сообщение от olc0267 Посмотреть сообщение
Да мне не нужно это объяснять, я не вчера родился.
Оказывается, пояснять надо. Если глобальная переменная находится в регистре, то нет смысла её объявлять volatile. То есть вы считаете с точностью до наоборот. Проблема только с тем, если переменная как раз таки находится в памяти. Но с памятью не выполняются операции. И перед выполнением компилятор перегружает эту переменную в рабочие регистры. А при оптимизации может с этими регистрами долго работать без обновления. В приведенном мной примере:
Код:
		for(char i=0; i‹200; i++)
		{
			if(b › TCNT1)
			{
			  PINA |= 2;
			  break;
			}
		}
компилятор по-разному должен обработать этот цикл. Если это статическая переменная, то он должен загрузить значение b в промежуточную пару рабочих регистров и сравнивать в цикле с текущим значением таймера. Если переменная b меняется, например, в прерывании, то каким образом объяснить это компилятору?!!! Тогда он должен каждый раз загружать переменную b до сравнения.
Вот для этих целей и вводится квалификатор volatile.
Цитата:
С точки зрения стандарта языка здесь нет ошибки. Но один компилятор совсем выкинул этот код, а другой более уважительно отнёсся к программисту.
Уважительно отнёсся к программисту тот компилятор который выкинул код. С точки зрения стандарта языка, здесь нет ошибки, - просто нет смысла. Задача компилятора построить программу так, чтобы она занимала как можно меньше памяти и выполнялась как можно быстрее. Это не ассемблер. Обратите внимание что одну и ту же программу откомпилировали на разных компиляторах и получили разное время выполнения. А вы хотите сделать задержку средствами языка. У вас сам подход неверный. Кто вам мешает применить конструкцию типа:
for(;--a;a==0) TCNT0;

Последний раз редактировалось SasaVitebsk; 01.02.2014 в 19:30.
SasaVitebsk вне форума  
Непрочитано 01.02.2014, 21:50  
olc0267
Почётный гражданин KAZUS.RU
 
Регистрация: 06.08.2008
Адрес: Ярославль
Сообщений: 1,505
Сказал спасибо: 115
Сказали Спасибо 1,314 раз(а) в 548 сообщении(ях)
olc0267 на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

Сообщение от SasaVitebsk Посмотреть сообщение
Оказывается, пояснять надо. Если глобальная переменная находится в регистре, то нет смысла её объявлять volatile.
В регистр она попадёт после того, как я её не объявил volatile. А уж если попала, тогда действительно бесполезно объявлять. Потому и говорю, что нарушаете причинно-следственную связь.
Сообщение от SasaVitebsk Посмотреть сообщение
И перед выполнением компилятор перегружает эту переменную в рабочие регистры.
А то я не знаю.
Сообщение от SasaVitebsk Посмотреть сообщение

for(;--a;a==0) TCNT0;
Вы хотели сказать

for(;a==0;--a) TCNT0;

Сейчас попробую и это откомпилить.

Последний раз редактировалось olc0267; 01.02.2014 в 21:54.
olc0267 вне форума  
Непрочитано 01.02.2014, 22:29  
olc0267
Почётный гражданин KAZUS.RU
 
Регистрация: 06.08.2008
Адрес: Ярославль
Сообщений: 1,505
Сказал спасибо: 115
Сказали Спасибо 1,314 раз(а) в 548 сообщении(ях)
olc0267 на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

сделано.
Если я напишу так
Код:
#include ‹avr/io.h›

void del(int a)
{
	
	for(; a==0; --a) ;
}

int main(void)
{
    while(1)
    {
        del(100); 
    }
}
компилятор Atmel Studio опять ничего не делает.
Если добавлю ещё команду
Код:
for(; a==0; --a) TCNT0;
( с точки зрения здравой логики - нахрена я обязан это делать?)
то получается
Код:
void del(int a)
{
	
	for(; a==0; --a) TCNT0;
  6c:	89 2b       	or	r24, r25
  6e:	09 f4       	brne	.+2      	; 0x72 ‹del+0x6›
  70:	82 b7       	in	r24, 0x32	; 50
  72:	08 95       	ret

00000074 ‹main›:

int main(void)
{
    while(1)
    {
        del(100); 
  74:	84 e6       	ldi	r24, 0x64	; 100
  76:	90 e0       	ldi	r25, 0x00	; 0
  78:	0e 94 36 00 	call	0x6c	; 0x6c ‹del›
  7c:	fb cf       	rjmp	.-10     	; 0x74 ‹main›

0000007e ‹_exit›:
  7e:	f8 94       	cli
Уже лучше. Но как человек в здравом уме должен догадаться, что так нужно сделать? Это прописано в стандарте языка Си? Это считать багом, или фичей компилятора?
Смотрим, что делает СV.
Код:
                 _del:
                 ; 0000 001C 	for(; a==0; --a) TCNT0;
                 ;	a -› Y+0
                 _0x4:
000048 81e8      	LD   R30,Y
000049 81f9      	LDD  R31,Y+1
00004a 9730      	SBIW R30,0
00004b f439      	BRNE _0x5
00004c b7e2      	IN   R30,0x32
00004d 81e8      	LD   R30,Y
00004e 81f9      	LDD  R31,Y+1
00004f 9731      	SBIW R30,1
000050 83e8      	ST   Y,R30
000051 83f9      	STD  Y+1,R31
000052 cff5      	RJMP _0x4
                 _0x5:
                 ; 0000 001D }
000053 9622      	ADIW R28,2
000054 9508      	RET
.....

                 ; 0000 008E while (1)
                 _0x6:
                 ; 0000 008F       {
                 ; 0000 0090       del(100);
000083 e6e4      	LDI  R30,LOW(100)
000084 e0f0      	LDI  R31,HIGH(100)
000085 93fa      	ST   -Y,R31
000086 93ea      	ST   -Y,R30
000087 dfc0      	RCALL _del
                 ; 0000 0091 
                 ; 0000 0092       }
000088 cffa      	RJMP _0x6
                 ; 0000 0093 }
                 _0x9:
000089 cfff      	RJMP _0x9
                 
                 	.CSEG
                 
                 	.CSEG
                 ;END OF CODE MARKER
                 __END_OF_CODE:
Но если я уберу TCNT0, то будет следующее

Код:
                 	.CSEG
                 _del:
                 ; 0000 001C 	for(; a==0; --a) ;
                 ;	a -› Y+0
                 _0x4:
000048 81e8      	LD   R30,Y
000049 81f9      	LDD  R31,Y+1
00004a 9730      	SBIW R30,0
00004b f421      	BRNE _0x5
00004c 9731      	SBIW R30,1
00004d 83e8      	ST   Y,R30
00004e 83f9      	STD  Y+1,R31
00004f cff8      	RJMP _0x4
                 _0x5:
                 ; 0000 001D }
000050 9622      	ADIW R28,2
000051 9508      	RET
Компилятор СV послушно делает всё что ему скажут. И не выпендривается.
Быть может, в этом причина "глючности" CV? Программисты сами глючат, а валят всё на компилятор.

Последний раз редактировалось olc0267; 01.02.2014 в 22:50.
olc0267 вне форума  
Непрочитано 01.02.2014, 22:56  
tempora
Почётный гражданин KAZUS.RU
 
Регистрация: 10.01.2007
Сообщений: 3,412
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
tempora на пути к лучшему
По умолчанию Re: CodeVisionAVR 2.60

Сообщение от olc0267 Посмотреть сообщение
с точки зрения здравой логики - нахрена я обязан это делать?
Смешной вопрос. Неужто никогда не встречались с девайсами, чтение из регистра которых сопровождается некоторыми действиями в них?
__________________
There's always more than one way to skin a cat.
tempora вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
CodeVisionAVR selevo Embedd С 11 26.02.2016 22:16
SD и CodeVisionAvr 2.04.4a sersne Микроконтроллеры, АЦП, память и т.д 29 24.03.2010 18:39
CodeVisionAVR V2.03.2 dimonbest Микроконтроллеры, АЦП, память и т.д 253 29.09.2009 22:37
New CodeVisionAVR 1.25.8 dimonbest Микроконтроллеры, АЦП, память и т.д 15 07.02.2008 12:56
Help CodeVisionAVR Serg79 Микроконтроллеры, АЦП, память и т.д 3 15.12.2005 23:32


Часовой пояс GMT +4, время: 02:13.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot