Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

Error message 306

Başlatan Extreme, 13 Kasım 2014, 14:48:32

Extreme

Merhaba forum üyeleri,

Kodları paylaşamıyorum ticari olduğu için fakat yorumlandırmanıza yönlendirmenize ihtiyacım var.

mplab program memory den baktığımda 2027 line olan bir yazılım üzerine eklemeler yaptım.

benim eklemelerimle 2150 line civarına kadar geldi.

Message[306] E:\MY BACKUP\TEST.ASM 55 : Crossing page boundary -- ensure page bits are set.

bolca bu hatadan almaya başladı ve program sapıttı.

benim bildiğim pagesel durumu (0x000-0x7ff, 0x800-0xfff.... ) gidiyor yani 0x7ff = 2047

bu aşamada programı hızlı bir şekilde nasıl çalışır duruma getirebilirim ?

pagesel ayarlarını yapmam mı gerekiyor ?

Basit bir örnek verirmisiniz ?

bu forumda sıkça paylaşılmış pclath (pagesel) fakat bir türlü kafam bu sistemi almadı.
https://www.picproje.org/index.php/topic,24684.0.html

yorumlarınız için teşekkürler.

Kabil ATICI

işlemcini büyüt .Aynı bacak sayısında daha büyük kapasitile işlemci kullan. Veya programını küçültmeye çalış.
Buradaki satır olayına takılma. Bazı komutlar 2 baytlıktır.Tabii derleyicinin linkerler için ekledikleri de var.
ambar7

Tagli

Bu işe yaramaz. Toplam bellek boyutundan bağımsız olarak, o ailedeki (PIC16) tüm modellerde page boyutu aynıdır. Bundan kurtulmak için PIC18'e geçmen gerekir ki ASM kodunu aktarmak tahminimce oldukça zahmetli olacaktır.

CALL ve GOTO'lardan önce uygun şekilde pagesel yapmalısın. Eğer programda GOTO veya RETLW tabloları varsa daha bir özen göstermen gerek. Ayrıca kesme kodunu da gözden geçirmelisin. Kesme başında eski PCLATH'ı yedekleyip uygun yeni değeri yüklemeli, dönüşte de eski değeri tekrar vermelisin.

Bu PCLATH olayı gerçekten insana kafayı yedirten bir şey. ASM ile kod yazıyorsan, PIC18'e geçmek için yeterli bir sebep bence.
Gökçe Tağlıoğlu

FEHMİ_ASM

   Komutların bazıları 11 bitlik olduğundan (goto ve call) pclath'a yüklenmeye çalışılırken
üst iki bit boşta kalıyor ve onun için sayfa seçimi yapmak gerekiyor. Bu sorunu makrolarla çözebileceğin konusunda bilgim yok ama araştırmalısın, belki işine yarayabilir.

  Flash'ta sanırım üç-dört komut sayfa dışında. Bu son komutlara nerelerden gelindiğini biliyorsan -ki sonradan ekleme yaptığın için bilmen lazım, işin kolay. Eğer bilmiyorsan debug yapman kaçınılmaz; sayfa dışına çıkış olacak/olabilecek komutların hemen öncesinde sayfa seçimi yapmalısın. "Bunu yaparken eklediğin her komut sayısı kadar ilk sayfa komut sayısı olan 2048'in altına program kendini iteleyecek, dolayısı ile sonradan eklediğin komutların (hatta daha düşük bir ihtimal asıl yazdığın ilk kodun en sondan bir kısmı) sayfa dışında kalabilecektir."

  Ben olsaydım, önce debug yapar ve pagesel komutlarını sayfa dışına gidecek yerlere goto ve call komutlarının hemen başına eklerdim.
  Bununla birlikte, assembly ile yazılan programlarda her sayfaya yazılan komut sayısının 2048'e çok yanaşmamasında fayda var, çünkü 2048'e kadar dayandığınızda sayfa seçimini kontrol etmek zorlaşabilir.  Böylelikle sonradan birkaç eklenti de daha rahatça yapılabilir. Her 2000 bloğun arasına nop koyabilirsiniz.
Örneğin kodları ;
0x000-0x7ff ; 0x800-0xfff değil de
0x000-0x7e0
nop,nop,...,nop
0x81f-0xfe0 gibi.

Interrupt fonksiyonunda da Tagli hocanın dediği gibi yedek almak için ekleme yapmalısın.

Extreme

Tekrardan merhaba,
Alıntı yapılan: Tagli - 13 Kasım 2014, 15:51:45
Ayrıca kesme kodunu da gözden geçirmelisin. Kesme başında eski PCLATH'ı yedekleyip uygun yeni değeri yüklemeli, dönüşte de eski değeri tekrar vermelisin.
Hocam bu dediğiniz kodları yazılımcı ilerleyen aşamalarda pagesel kullanımı için eklemiş. Hali hazırda mevcut gibi gözüküyor.

Alıntı yapılan: ambar7 - 13 Kasım 2014, 15:00:50
işlemcini büyüt .Aynı bacak sayısında daha büyük kapasitile işlemci kullan. Veya programını küçültmeye çalış.
Şu an pici yükseltmemiz mümkün değil malasef.



Programın ilk hali(2000 Program Counter Sorunsuz çalışıyor)
Ben test rutini ekleyince 2047 Program Counter aşıyor.
Aşağıda verdiğim kodlarda en basitleşmiş halini vermeye çalıştım.
Bana basitçe pagesel yolu gösterecek bilgili arkadaşlar varsa çok sevinirim.

Kısaca program şöyle çalışıyor


Değişkenleri tanımlanıyor. port tanımlıyor. değişken ilklendiyor.
sonra timer1 set edip timer1 boş döngüsünü giriyor.(timer1=300usyi tamamlamak için)
Programı kesmelerden yönetiyor. kesmedede normal rutin var.
Ben normal rutinin üzerine 250 cycle bağımsız bir test rutini eklemek istiyorum.


Programın test rutini eklendikten sonraki hali ( 2200 Program Counter - Program sapıtıyor )
LIST   P=PIC16F887
include "p16f887.inc"
%%%%%%%%değişken tanımlamaları
;**********************************************************************
		   ORG     0x0000              ; processor reset vector
		  GOTO    baslangic         	; go to beginning of program
;**********************************************************************
;*****						  Interrupt bölümü 					*****
			ORG     	0x0004             ; interrupt vector location
			MOVWF   	w_temp             ; copy w to temp register
			MOVF	STATUS,w           ; move status to be saved into W
		   	CLRF    	STATUS          	 ; Bank0, reagardless of current bank, Clears IRP,RP0,RP1
			MOVWF	status_temp        ; save status to bank 0 register
			MOVF    	PCLATH,w           ; only required if using pages 1, 2 or 3
			MOVWF   	pclath_temp        ; save pclath
			CLRF    	PCLATH          	 ; page 0
;***** 	Interrupt rutini baslangici  	*****
			BANKSEL 	PIR1
			BTFSS   	PIR1,TMR1IF       ; timer 1 interrupt geldi kontrolü
			GOTO	interrupt_sonu
			BCF     	PIR1,TMR1IF       ; interrupt flagını temizle
			MOVLW   	0xFC 
			MOVWF   	TMR1H             ;Set timer 1 to 312,5us timeout period (315,6)
			MOVLW   	0xFD
			MOVWF   	TMR1L
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;******						eklemek istediğim bölüm					   ********
			BTFSC		SelfFlag,testbitti			;test bitti mi	
			GOTO		normal rutin
			DECFSZ 		SelfCounter,f                      ;250cycle
			GOTO 		test rutin
			BSF			SelfFlag,testbitti		
;**************************************************************************
test rutin
;***buraya kodlar yeni kodlar eklenecek****


;=====================  test Interrupt rutini sonu =========================
test_interrupt_sonu
		   	BANKSEL 	pclath_temp			;1,8us
			MOVF    	pclath_temp,w      ; restore pclath
			MOVWF	  	PCLATH             ;
		   	MOVF    	status_temp,w   	; to set to original bank state
			MOVWF	  	STATUS             ; restore STATUS
			MOVF    	w_temp,w           ; restore pre-isr W register contents
			RETFIE    
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
normal rutin
%%%%%%%%normal rutin
;=====================  Interrupt rutini sonu =========================
interrupt_sonu
		   	BANKSEL 	pclath_temp			;1,8us
			MOVF    	pclath_temp,w      ; restore pclath
			MOVWF	  	PCLATH             ;
		   	MOVF    	status_temp,w   	; to set to original bank state
			MOVWF	  	STATUS             ; restore STATUS
			MOVF    	w_temp,w           ; restore pre-isr W register contents
			RETFIE    
;======================================================================
baslangic

%%%%%%%%port tanımlamaları (burdan bir kez geçiyor)
%%%%%%%% değişken ilklendir (burdan bir kez geçiyor)

;SETUP TIMER1 ========================================================
			MOVLW   	0xFC		
		   	MOVWF   	TMR1H            		;Set timer 1 to (315,6) timeout period
		  	MOVLW   	0xFD
			MOVWF   	TMR1L
			BSF     	T1CON,0          		;Timer1'i çalistir
;MAIN PROGRAM LOOP ===================================================

TIMER1_RB0_INT_BEKLE
			CLRWDT
			NOP
			NOP
			NOP
			GOTO		TIMER1_RB0_INT_BEKLE

%%%%%%%% fonksiyonlar

end


Kabil ATICI

Senin olay çıkmaz sokak.
Yapabileceğin sıkça kullandığı 3-4 satırlık kodları alt program haline getirebilirsin. Nop varsa silebilir veya döngü ile değiştirebilirsin.(1-2 tane için değil).
Kullandığın macro varsa ve uzunsa bunları alt program haline getirebilirsin. birden fazla bit aynı grupta alt alta işlem yapılıyorsa, AND, OR işlemleri ile değiştirebilirsin,

Bunları zaten yaptım diyorsan işlemci sınırına gelmişsin demektir.
ambar7

Extreme

Alıntı yapılan: ambar7 - 17 Kasım 2014, 11:27:42
Senin olay çıkmaz sokak.
Yapabileceğin sıkça kullandığı 3-4 satırlık kodları alt program haline getirebilirsin. Nop varsa silebilir veya döngü ile değiştirebilirsin.(1-2 tane için değil).
Kullandığın macro varsa ve uzunsa bunları alt program haline getirebilirsin. birden fazla bit aynı grupta alt alta işlem yapılıyorsa, AND, OR işlemleri ile değiştirebilirsin,

Bunları zaten yaptım diyorsan işlemci sınırına gelmişsin demektir.

Hocam bunların hepsi yapılmış.

Ayrıca ben şu an 2200 program counter diyorum ama bu test rutinine eklemelerle 2500 program counterı bulur.

Benim bu picle pagesel yapmaktan başka çarem gözükmüyor .

Kabil ATICI

Pagesel yaparken bazı registerlerin o pageselde çalışıp/çalışmayacağını dikkate almalısın.
ambar7

Tagli

#8
Kodu yazan adam belli ki tek page üzerinde kalacağını varsaymış. Sen araya kendi kodunu ekleyince adamın tüm kodunu kaydırıyorsun, haliyle işler sapıtıyor. Adamın tüm tablolarını, goto ve call komutlarını gözden geçirmeye çalışmak anlamsız bir eziyet. Onun yerine sen kendi kodunu 2. page'e koy, kesmeden oraya PCLATH ayarını da yaparak call veya goto ile git. Böylece orijinal kod ilk page'de kalmaya devam eder ve bozulmaz. Başka türlü işin içinden çıkamazsın.

Alıntı yapılan: ambar7 - 17 Kasım 2014, 11:57:03
Pagesel yaparken bazı registerlerin o pageselde çalışıp/çalışmayacağını dikkate almalısın.
Bunu anlamadım. Page ile Bank ayrı kavramlar. İçinde bulunulan page'in register erişimi ile bir ilgisi yok.
Gökçe Tağlıoğlu

Kabil ATICI

TRIS işlemini BANK0'da, PORT işlemini BANK1'de yapmamak gibi..
Yaparsa ne olur?
ambar7

Extreme

#10
Alıntı yapılan: ambar7 - 17 Kasım 2014, 12:08:51
TRIS işlemini BANK0'da, PORT işlemini BANK1'de yapmamak gibi..
Yaparsa ne olur?

Hocam bank kullanımıyla sıkıntım yok.

Alıntı yapılan: Tagli - 17 Kasım 2014, 11:59:00
Kodu yazan adam belli ki tek page üzerinde kalacağını varsaymış. Sen araya kendi kodunu ekleyince adamın tüm kodunu kaydırıyorsun, haliyle işler sapıtıyor. Adamın tüm tablolarını, goto ve call komutlarını gözden geçirmeye çalışmak anlamsız bir eziyet. Onun yerine sen kendi kodunu 2. page'e koy, kesmeden oraya PCLATH ayarını da yaparak call veya goto ile git. Böylece orijinal kod ilk page'de kalmaya devam eder ve bozulmaz. Başka türlü işin içinden çıkamazsın.

Hocam bende tam olarak bunu yapmaya çalışıyorum.

Zaten dikkat ederseniz . benim ekleyeceğim kod (test rutin ) , adamın yazdığı (normal rutin)den çok bağımsız olabilir.

Şu an açıkcası 2 ay önce asm diline giriş yaptım. Pageseli ilk defa yapmaya çalışıyorum.

Dediğiniz işlemi yapmaya çalışıyorum(2.page e koyma işlemi).

LIST   P=PIC16F887
include "p16f887.inc"
%%%%%%%%değişken tanımlamaları
;**********************************************************************
		   ORG     0x0000              ; processor reset vector
		  GOTO    baslangic         	; go to beginning of program
;**********************************************************************
;*****						  Interrupt bölümü 					*****
			ORG     	0x0004             ; interrupt vector location
			MOVWF   	w_temp             ; copy w to temp register
			MOVF	STATUS,w           ; move status to be saved into W
		   	CLRF    	STATUS          	 ; Bank0, reagardless of current bank, Clears IRP,RP0,RP1
			MOVWF	status_temp        ; save status to bank 0 register
			MOVF    	PCLATH,w           ; only required if using pages 1, 2 or 3
			MOVWF   	pclath_temp        ; save pclath
			CLRF    	PCLATH          	 ; page 0
;***** 	Interrupt rutini baslangici  	*****
			BANKSEL 	PIR1
			BTFSS   	PIR1,TMR1IF       ; timer 1 interrupt geldi kontrolü
			GOTO	interrupt_sonu
			BCF     	PIR1,TMR1IF       ; interrupt flagını temizle
			MOVLW   	0xFC 
			MOVWF   	TMR1H             ;Set timer 1 to 312,5us timeout period (315,6)
			MOVLW   	0xFD
			MOVWF   	TMR1L
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;******						eklemek istediğim bölüm					   ********
			BTFSC		SelfFlag,testbitti			;test bitti mi	
			GOTO		normal rutin
                        movlw             h'02'
                        movwf             PCLATH                     ;page2yi seç .
                        ORG                     0XFFF
			DECFSZ 		SelfCounter,f                      ;250cycle
			GOTO 		test rutin
			BSF			SelfFlag,testbitti
                        GOTO 		test rutin		
;**************************************************************************

test rutin
;***buraya kodlar yeni kodlar eklenecek****


;=====================  test Interrupt rutini sonu =========================
test_interrupt_sonu
		   	BANKSEL 	pclath_temp			;1,8us
			MOVF    	pclath_temp,w      ; restore pclath
			MOVWF	  	PCLATH             ;
		   	MOVF    	status_temp,w   	; to set to original bank state
			MOVWF	  	STATUS             ; restore STATUS
			MOVF    	w_temp,w           ; restore pre-isr W register contents
			RETFIE    
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
normal rutin
%%%%%%%%normal rutin
;=====================  Interrupt rutini sonu =========================
interrupt_sonu
		   	BANKSEL 	pclath_temp			;1,8us
			MOVF    	pclath_temp,w      ; restore pclath
			MOVWF	  	PCLATH             ;
		   	MOVF    	status_temp,w   	; to set to original bank state
			MOVWF	  	STATUS             ; restore STATUS
			MOVF    	w_temp,w           ; restore pre-isr W register contents
			RETFIE    
;======================================================================
baslangic

%%%%%%%%port tanımlamaları (burdan bir kez geçiyor)
%%%%%%%% değişken ilklendir (burdan bir kez geçiyor)

;SETUP TIMER1 ========================================================
			MOVLW   	0xFC		
		   	MOVWF   	TMR1H            		;Set timer 1 to (315,6) timeout period
		  	MOVLW   	0xFD
			MOVWF   	TMR1L
			BSF     	T1CON,0          		;Timer1'i çalistir
;MAIN PROGRAM LOOP ===================================================

TIMER1_RB0_INT_BEKLE
			CLRWDT
			NOP
			NOP
			NOP
			GOTO		TIMER1_RB0_INT_BEKLE

%%%%%%%% fonksiyonlar

end


Bu şekilde olur mu ?

Tagli

Öncelikle, kodunu ORG ifadesi ile 0x800'den sonra bir yere yerleştirmen gerekiyor. Bence biraz daha iler koyman daha uygun olabilir, 0x900 gibi mesela.
Kodunun giriş etiketi TEST_KODU olsun. Bu durumda, kesme kodu veya herhangi bir yerden (page0 üzerinde olduğunu varsayıyorum) TEST_KODU'da goto veya call yapacağın zaman, öncelikle "pagesel TEST_KODU" demen gerekiyor. Bu ifade PCLATH'ın içine doğru değeri atacak olan gerekli bsf, bcf komutlarına dönüşüyor. Bunu kendin elle de yapabilirsin ama gerek yok. İşin bittikten sonra, return ile dönerken bir şey yapman gerekmiyor, ama döner dönmez, döndüğün yerde PCLATH'ı eski haline getirmelisin. Yoksa döndükten sonra page0 içinde dolaşan tüm goto ve call komutları saçmalamaya başlar. Gittiğin yerden return değil de goto ile dönüyorsan, goto'dan önce yine pagesel yapmalısın.

Kendi kodunu şuna benzer bir şekilde çağırmalısın:
pagesel TEST_KODU
call TEST_KODU
pagesel $ ;PCLATH'ı eski haline getirmek için
Gökçe Tağlıoğlu

Extreme

#12
Timer1 v.s. unutalım sadece basitçe pclath çalıştırmaya çalışıyorum hocam

Sadece pagesele odaklanarak bir yazılım düzenledim. sadece pagesel çalışması önemli burda

Nerede hata yapıyorum ?




Tagli

Satır 24'teki pagesel gereksiz, çünkü PCLATH zaten page1'e göre ayarlı. Ama, satır 28'deki goto'dan önce "pagesel baslangic" demen gerekiyor çünkü gideceğin adres page0'da ama sen o sırada page1'desin.

Bu arada, satır 13'teki pagesel de gereksiz, çünkü zaten page0 içinden yine page0 içinde bir yere gidiyorsun.
Gökçe Tağlıoğlu

Extreme

#14
Hocam satır numarası 23e bakınız .

goto 102 diyor

00001    0000 0010 

aslında goto 902 olmalı

10001    0000 0010

Yani PCLATH registerındaki değeri almıyor page 0 kabul ediyor.



LIST	P=PIC16F887
		include	"p16f887.inc"
		errorlevel -302
		
;===========================================
		ORG	0x0000
baslangic
		CLRF	PCLATH
		BTFSC	RCSTA,CREN
		GOTO	normal_1
		GOTO	test_1
normal_1
		GOTO	normal_kod
test_1
		PAGESEL	test_kodu
		GOTO	test_kodu
		
		
;===========================================
		ORG 0X900
test_kodu
		BTFSS	RCSTA,CREN
		GOTO	test_kodu2
test_kodu2
		BCF	RCSTA,CREN
		PAGESEL baslangic
		GOTO	baslangic
		
;========================================
		ORG	0x250
normal_kod
		BTFSS	RCSTA,CREN
		GOTO	normal_kod2
normal_kod2
		BCF	RCSTA,CREN
		GOTO	baslangic
		
		END



message 306 önemsemiycekmiyim ?

çokça message 306 hatası alıyor ?