PicBasic BOOTLOADER

Başlatan hiddenman32, 05 Temmuz 2004, 13:08:18

hiddenman32

Hepinize sevgi ve selamlar.

Yapmakta oldugum bir projede BOOTLOADER ile ilgili sorun yasiyorum. Yardımlarınız için şimdiden teşekkürler.

Sorunum şu. PicBasic pro kullanarak bir bootloader yazılımı hazırladım. Daha dogurusu hazırlamaya çalıştım. Buna bağlı olarakta bir delphide yazılım hazırladım.

Pic16f88 kullanıyorum. Loader dosyasını pic'e aktardıktan sonra devreye bağladığımda ve yazılımı çalıştırdığımda yükleyeceğim hex dosyasınıda pic' aktarabiliyorum.

FAKAT:

Yeni yüklediğim modülü bir türlü çalıştırmayı başaramadım. Kaynakları inceledim. Bu konuda yazılmış dosyaları inceledim ama sonuç alamadım. Reset vector ve int vector ile ilgili sorunum olduğunu tahmin ediyorum ama işin doğrusu bu vektorleride basic ile kullanamıyorum.

Çünkü 0x0h adresine erişim iznim basicte yok veya ben bulamadım.

Kaynak kodunuda gönderiyorum. Kısaca program şöyle çalışıyor.

gerekli ayarlamalardan sonra sistem bir süre bootloader açılış komutunun gelmesini bekliyor sonrasında bu kod gelirse okuma veya kaydetme moduna geçiyor. Gelmezse normal programın çalışmasına geçmesi gerekiyor.

basicteki writecode komutuda çalışmadığı için o modülü kendim yazmak zorunda kaldım.

Sizlerden ricam eğer bu konuda bilgisi olan varsa yazdığım koddaki hatayı veya int ile reset vektörlerini basıcte nasıl kullanacağımı açıklayan olursa sevinirim.

Hepinize çalışmalarınızda başarılar dilerim. Siyeyi hazırlayan arkadaşlarada teşekkürler.


Not:xor komutuda picbasic te çalışmıyor checksum işlemini o yüzden uzun yoldan yapmak zorunda kaldım.
'************************************************************'
@ DEVICE PIC16F88,INTRC_OSC_NOCLKOUT,WDT_OFF,MCLR_OFF,PWRT_ON, BOD_ON,LVP_OFF,CPD_OFF,PROTECT_OFF,CCPMX_ON

'***********************************************************
DEFINE SHIFT_PAUSEUS 100   
DEFINE LCD_DREG PORTA                                              
DEFINE LCD_DBIT 0                                                
DEFINE LCD_RSREG PORTB                                           
DEFINE LCD_RSBIT 1                                               
DEFINE LCD_EREG PORTB                                            
DEFINE LCD_EBIT 3                                                
DEFINE LCD_BITS 4                                                
DEFINE LCD_LINES 2                                               
DEFINE LCD_COMMANDUS 2000                                        
DEFINE LCD_DATAUS 50                                             

DEFINE LOADER_USED 1

'************************************************************
DEFINE OSC 8             
DEFINE HSER_RCSTA 90h ' Set receive register to receiver enabled
DEFINE HSER_TXSTA 24h ' Set transmit register to transmitter enabled
DEFINE HSER_BAUD 38400 ' Set baud rate
DEFINE HSER_SPBRG 12  ' Set SPBRG directly 
DEFINE HSER_CLROERR


li VAR BYTE
lcmd1 VAR BYTE
lcmd2 VAR BYTE
lcmd3 VAR BYTE
lcmd4 VAR BYTE
lcmd5 VAR BYTE
ladd VAR WORD
ladd2 VAR WORD
lvalue VAR WORD
llcdbar VAR WORD
checksum VAR BYTE
checksumx VAR BYTE
config_reg VAR BYTE


; ilk açılışlar ve ayarları
osccon=%01111110    ;8 mhz oscillator setup
ansel=0             ;analog mode Disable select digital io
CMCON=%00000111     ;COMPARATOR Disable
adcon0.0=0          ;Disable a/d
pie1=%00100000
pie2=0              ;comparator int Disable
pir1=0
pir2=0              ;EEPROM flag bits
OPTION_REG.7 = 0    ;PORTB pull-up Enable
CVRCON.7 = 0        ;Disable VREF, bit7 

config_reg=192
PORTB.3=0     ; Disable lcd
PORTB.7=0     ; set clr
PORTB.6=0     ; reset clk
Pause 10
PORTB.7=1    ; reset clr
ShiftOut PORTA.1,PORTB.6,1,[config_reg\8]


;0 out 1  Input
TRISA=%00010101     ;rxtx, IRled, 0, sw, lcd, lcd(sw2), lcd(ent_data), lcd(sw1)
TRISB=%00000101     ;ent_clr, ent_clk, TX, ses, lcd_enable, RX, lcd_rs, IR_reciever
PORTA.7=1           ;rx tx bağlantısı aktif
Pause 100

GoTo loadercontrol


main:
@ org 0240h












;************************************************************
@ org 0ca0h
loadercontrol:

Disable
LCDOut $fe,1,$fe,$85,"Pleace Waiting"
PORTA.7=1
HSerin 3000,cikis,[lcmd1,lcmd2,lcmd3,lcmd4,lcmd5]
LCDOut $fe,1
       IF lcmd1="B" Then
       IF lcmd2="O" Then
       IF lcmd3="O" Then
       IF lcmd4="T" Then     
            LCDOut $fe,1,$fe,$80,"Address="
            LCDOut $fe,$8e,"Code="
       IF lcmd5="R" Then            
            GoTo Loaderread
       EndIF
       IF lcmd5="W" Then            
            GoTo Loaderwrite
       EndIF
       EndIF
       EndIF
       EndIF
       EndIF

GoTo cikis

;*************loader Read****************
LoaderRead:

lx:
HSerin 3000,cikis,[lcmd1,ladd.byte1,ladd.byte0]

IF lcmd1="c" Then
    readcode ladd,lvalue
    llcdbar=ladd/100
    llcdbar=llcdbar*24
    llcdbar=(llcdbar/40)+$c0
    ladd2=ladd
    GoSub check
EndIF

IF lcmd1="d" Then
    Read ladd,lvalue
    lvalue.byte1=0
    llcdbar=(24*ladd)/255
    llcdbar=llcdbar+$c0
    ladd2=ladd+$2100
    GoSub check    
EndIF

    LCDOut $fe,$88,#ladd
    LCDOut $fe,$93,#lvalue
    For li=$c0 to llcdbar
        LCDOut $fe,li,$FF
    Next

    HSerout ["C",ladd2.byte1,ladd2.byte0,lvalue.byte1,lvalue.byte0,checksum,"e"]

IF lcmd1="E" Then cikis

GoTo lx

;*************loader Write****************
loaderwrite:

wrt:
    HSerin 1000,cikis,[lcmd1,ladd.byte1,ladd.byte0,lvalue.byte1,lvalue.byte0,CHECKSUMX]
    ladd2=ladd
    GoSub check

IF lcmd1="E" Then
    HSerout ["OK"]
    GoTo cikis
EndIF

IF lcmd1="S" Then
    erasecode ladd+$240
    HSerout ["OK"]
    GoTo wrt
EndIF

IF checksum<>checksumx Then
    HSerout ["ER"]
    GoTo wrt    
Else
    LCDOut $fe,$88,#ladd
    LCDOut $fe,$93,#lvalue
    IF lcmd1="W" Then
    ladd=ladd+$240
        llcdbar=ladd/100
        llcdbar=llcdbar*24
        llcdbar=(llcdbar/40)+$c0
        GoSub writeflash
    EndIF
    IF lcmd1="Y" Then
    LCDOut $fe,$8e,"Data="
        llcdbar=(24*ladd)/255
        llcdbar=llcdbar+$c0
        Write ladd,lvalue
    EndIF
    For li=$c0 to llcdbar
        LCDOut $fe,li,$FF
    Next   
HSerout ["OK"]
EndIF

GoTo wrt

;***********
writeflash:
Disable
pir2.4=1
pie2.4=1
eecon1.4=0 ;free
eecon1.7=1  ;eepgd
eecon1.2=1  ;wren
    eeadrh=ladd.byte1
    eeadr=ladd.byte0
    eedath=lvalue.byte1
    eedata=lvalue.byte0
eecon2=$55
eecon2=$AA
eecon1.1=1
@ nop
@ nop    
eecon1.2=0
Enable    
Return

;**********check************
check:
checksum=ladd2.9
checksum=checksum << 1
checksum=checksum + ladd2.8
checksum=checksum << 1
checksum=checksum + ladd2.1
checksum=checksum << 1
checksum=checksum + ladd2.0
checksum=checksum << 1
checksum=checksum + lvalue.9
checksum=checksum << 1
checksum=checksum + lvalue.8
checksum=checksum << 1
checksum=checksum + lvalue.1
checksum=checksum << 1
checksum=checksum + lvalue.0
Return

;***********************************************************

cikis:
Enable
GoTo main



End

axanc

selam..

öncelikle kolay gelsin, ben de kendi bootloader programımı yaptım, zevkli ve zor bir iştir bilirim... tabi ben bootloader'ı assemble ile yazdım.. nese konumuza gelelim...:

entegrenin program hafızasında 0x0000h, 0x0001h, 0x0002h, 0x0003h ve 0x0004h özel yerlere sahiptir, yani düşünce olarak, entegreye reset atıldığında veya ilk enerji verildiğinde program akışı otomatik olarak 0x0000'dan başlar, herhangi bir interrupt yani kesme oluştuğunda ise 0x0004'e gider.. işte bu sebepten 0x0000'daki komutlar program akışını senin bootloader'a göndermelidir ve seri porttan gönderilen programın 0x0000 ile başlayan kodları o adreslere yazılmak yerine başka yerde tutulmalıdır, örneğin bootloader'ın kapladığı adres içinde bir yerde ve program yazımı sonrası saklanan bu kodlar nereye gönderiyorsa oraya dallanılmalıdır... bootloader içinde de kesmelerin hepsini kapatman gerekir.. ve bence checksum kontrolü yapmayı geç, pek gerek yok, hatta hiç gerek yok, o kontrolleri bilgisayara yaptır, ve hex  dosyasını satır satır gönder..
org 0x1f34
nop
nop
nop
nop
'örneğin bu 4 nop yerine kullanıcının reset vektör bilgileri konacak...


umarım yardımcı olur bu söylediklerim, benim gitmem gerekiyor, öbür gelişimde daha ayrıntılı yazarım...

yahoo groups'ta "PicProjeUp5"da benim yazdığım bootloader programı, hex dosyası ve açıklamaları var... asm'yi koymadım ne yazıkki...

bye..
Uzmanlık: Bilgisayar Müh. öğrenci Derleyici: PicBasic Pro Compiler Ver. 2.45 Program: Proteus 6.2.5 ve MCSP

hiddenman32

Yardımların için sağol. Aslında sorunumu biliyorum reset ve int vektörlerini basic'te kontrol edemiyorum. asm ile yazıldığında buna direk olarak müdahele mümkün org dedikten sonra iş çözülüyor ama basic'te bunu beceremedim.

basic bu vektörleri kendisi istedği gibi yönlendiriyor ve 5h ten itibaren kendi alt rutinlerini bellege yerleştiriyor.Daha sonra int vektörünüde bu yerleşime göre kendisi ayarlıyor. Sonradan 0h adresine erişimi yasaklıyor. Bir şekilde ulaşsamda ki ulaştım sonradan yeni yüklediğim program örneğin 240h adresinden başlatarak pic'e yazdığımda derleme anındaki orjinal adresleri aynen kaldığı için pic belleğindeki gitmesi gereken yere değil farklı yere gitmiş oluyor. Belki hex dosyasını okuduktan sonra dallanma adreslerini 240h arttıran bir modül ilavesi bunu çözecektir ama bu yola başvurmadan bu iş yapılabiliyor ama basic'te nasıl?

Asm ile yazmakta diretmem bir ay sonra askere gideceğim. Bu işe benden sonra devam edecekler ve malesef asm bilen yok 1 yıl projenin ertelenmesi hem maddi hem manevi sorun yaratacak....

checksum rs232 ile pic arasındaki haberleşmenin doğruluğunu kontrol için herhengibir nedenle hatalı veri gelirse yeniden istemek ve göndermek için.

Ama önerilerin doğrultusunda yeniden gözden geçireceğim.

Tekrar teşekkürler.

Herhalde basic plus'ta kendileri bu rutinleri hazır olarak sattıkları için böyle bir yolada başvurmuş olabilirler diyede düşünmekten kendimi de alamıyorum doğrusu.

İyi akşamlar tekrar görüşmek üzere.

Not:PicProjeUp5 'taki dosyalar çekmek istedim ama sanırım bir sorun var.

axanc

dosyalara bakarım, sorunlu ise tekrar yüklerim...

bu arada senin kodlarını inceledikten sonra dün gece biras denemeler yaptım ve şunun farkına vardım, PBP ile 0x0000h'a ulaşılamıyor; ancak 0x0001h'a ulaşma izni var... yanlız kullandığın bazı komutlar da 0x0001-5h arasını kullanıyor (örneğin "Hserin" komutu) işte bu komutları kullanmadan yapman lazım ki bu da nerseyse assemble'a geliyor, bi de senin sandığın gibi writecode komutunda bir sorun yokmuş, yani Writecode komutu çalışıyor, ancak önce ÜstByte'ı yazıyor...

MicroCodeStudio'nun bootloader kodunda "kullanıcının reset" vektör bilgilerini önceden anlattığım gibi başka bir yerde saklama prensibi var, aslında olay oldukça kolaymış, ancak giriş yaparken zorlanman oldukça normal.. sen en iyisi MCSP'in bootloader için yazdığı hex dosyalalarını bir disassmbler ile assemble'a çevir ve onları incele..

mesela MCSP'da, reset sonrası 250ms içinde PIC'e 19200baud'da "0xF0" gönderiliyor, PIC bilgiyi alınca "0xA0" gönderiyor ve komut bekliyor, gelen komuta göre işlemleri aparken de Flash'a ve/veya EEPROM'A yazdığı bilgileri tekrar bilgisayar'a gönderiyor, yani bir çeşit doğrulama yapılmasını sağlıyor... sonra gelen bir komut ile "kullanıcı reset vektörünün" dediklerini yapıyor, yani esas program başlamış oluyor.. tabi esas programa geçmeden önce bütün değişiklikleri default hale getiriyor...

:)...
Uzmanlık: Bilgisayar Müh. öğrenci Derleyici: PicBasic Pro Compiler Ver. 2.45 Program: Proteus 6.2.5 ve MCSP

hiddenman32

Malesef elimde mcsp ve hex dosyaları yok. Nereden bulabilirim?

Writecode hatalı çalışıyor. 877 ile denemedim ama 88 ile sorun var kayıt etme işlemini yapmıyor ve sistem bu kod çalıştığında kendini kitliyor belki bendeki sürümle ilgili bir sorunda olabilir.

İlgine teşekkürler.Araştırmaya devam edeceğim.

axanc

https://www.picproje.org/index.php/topic,3682&view=newest

buradan bulabilirsin, ancak 16f88'i desteklemiyormuş gibi birşeyler vardı, yada 16f88 için ICD'yi mi desteklemiyormuş ne.. takıl kafana göre... ben ağustos'un ortasına kadar gidiyorum, sana askerde başarılar.. :)
Uzmanlık: Bilgisayar Müh. öğrenci Derleyici: PicBasic Pro Compiler Ver. 2.45 Program: Proteus 6.2.5 ve MCSP