Merhaba arkadaşlar
Kullandığım mikro işlemcinin hafıza yetmediğinden dolayı mikro işlemcinin RAM kısmını ROM gibi kullanmak istiyorum daha önce bu şekilde kullanan varmı varsa tecrübelerini bizimle paylaşabilirmi.
RAM kısmını ROM gibi kullanamazsın, belki tersi mümkün olabilir sadece.
Öncelikle, RAM ve ROM dediğimiz şeylere açıklık getirelim, sonradan işler karışmasın.
ROM -> Program hafızası. Çalıştırılan programın yanısıra pek çok PIC'te bu bölgede sabit verileri de saklamak mümkün
RAM -> Veri hafızası. Çalışma sırasında kullanılan değişkenleri vs. saklar. Elektrik kesintisinde verileri kaybolur.
Öncelikle, kullandığın PIC'in modeli nedir?
Sana yetmeyen hafıza hangisi?
Eğer program hafızası yetmiyorsa işin zor. Harici bir EEPROM kullanarak (adeta hard disk gibi) o programın o anda çalışacak kısmını okuyup program hafızasında kullanılmayan bir bölgeye yazıp çalıştırabilirsin. Oldukça karmaşık bir işlem olur, şimdiye kadar da yapanı duymadım. Üstelik ROM'un ömrünü de tüketir. Bu işe girişeceksen, öncelikle daha yaygın bir uygulama olan bootloader'ları öğrenmeni tavsiye ederim. Ama en doğrusu daha yüksek hafızalı bir PIC'e geçmek veya programı optimize ederek hafıza kullanımını azaltmak olur.
Eğer veri hafızası yetmiyorsa önerebileceğim çözümler yine aynı. Program hafızasında veri saklaman mümkün. Bu veri sabit bir değerse sorun yok. Ama değilse, sürekli olarak yazma yapman kısa sürede program hafızasının ömrünü tüketir.
Seçeneklerin uygulamanın yapısına ve işleyişine göre de değişiklik gösterecektir.
Merhaba. ROM bellekte aşağıdaki gibi dizi veya değişken tanımlıyorum, ancak bunlara herhangi bir değer yükleyemiyorum. Yükleniş şekli mi farklı acaba, yoksa dizi tanımı mı yanlış?
rom volatile unsigned int Arr1[9]; //Programın başında tanımlıyorum
.
.
//Fonksiyon//
Arr1 [0] = 0xff00; // Hiçbirşey yüklenmiyor
.
.
C18 kullanıyorum ve romda tanımladığım değişkenlerde de aynı durum var.
Alıntı yapılan: FEHMİ_ASM - 02 Mart 2013, 20:09:53
Merhaba. ROM bellekte aşağıdaki gibi dizi veya değişken tanımlıyorum, ancak bunlara herhangi bir değer yükleyemiyorum. Yükleniş şekli mi farklı acaba, yoksa dizi tanımı mı yanlış?
rom volatile unsigned int Arr1[9]; //Programın başında tanımlıyorum
.
.
//Fonksiyon//
Arr1 [0] = 0xff00; // Hiçbirşey yüklenmiyor
.
.
C18 kullanıyorum ve romda tanımladığım değişkenlerde de aynı durum var.
Hocam PIC mikrodenetleyicilerin işlemcileri Harvard mimarisi yapısındadır. Yani program hafızası ile ram hafıza ayrıdır.
Alıntı Yap
Note:
When writing to a rom variable, the compiler uses a TBLWT instruction; however, there may be additional application code that needs to be written based on the type of memory being utilized. See the data sheet for more information.
rom ile tanımlı değişkenlere yazarken move türevi komutlar değil, TBLWT komutu kullanılıyor. Diziler ise bellekte pointer(işaretçisi) ile tutuluyor. Yani siz bir dizi oluşturup onun bir elemanına yazmaya çalıştığınızda sanki dizi işaretçisi RAM belleği işaret ediyormuş gibi adres hesaplanıyor. Hesaplanan yanlış adrese MOVE türevi komutlarla bilgi yazılıyor. Dolayısıyla program hafızasında istenilen amaca ulaşılamıyor olabilir diye düşünüyorum. Emin değilim. C18 benzeri derleyicileri kullanmadım pek iyi tanımıyorum.
Dizi sorunu bildiğim kadarıyla böyle açıklanabilir ama son cümlenize birşey diyemeyeceğim.
Alıntı YapC18 kullanıyorum ve romda tanımladığım değişkenlerde de aynı durum var.
Eğer burada da sorun varsa veri sayfalarını incelemek gerekli bir detay olabilir.
Vatandaşın biri aşağıdaki gibi yapmış. Artık, zaten sabit olacak dizi verilerini diziye bu şekilde alabiliyorum. Şimdi bunları diziden almaya geldi. Buradan verileri karışık bir şekilde okuyabilmeliyim. Bunu TBLRD ile mi yapacağım?
const rom unsigned char roots[9] =
{ 0, 1, 1, 1, 2, 2, 2, 2, 2, 3};
Mikro c'de const komutu ile belirlediğimiz değişken ram'dan yemiyordu.Bu sayede kod optimasyonu sağlayabiliyorum.Acaba kullandığınız derleyici program nedir ?
Birde yukarıda arkadaş işin karmaşıklığından bahsetmiş zaten.Eprom kullanmak ve oradan kalan bilgiyi almak çok zor gibime geliyor düşündümde.
J veya K serisi PIC'lerde RAM ve ROM oranları dahada artıyor bir göz atın derim..
iyi forumlar.
C'de normal bir değişkene erişilebildiği gibi flash hafızasına da erişilebiliyor olması lazım. Yani
Arr1[0] = 0xff00; gibi bir satırı yazabiliyor olman lazım. Okumada zaten sorun çıkmaz. Ancak yazma işlemi biraz daha karmaşık, bloklar halinde yapılması gerekiyor. Derleyici bu işi kendisi hallediyor olabilir ama yine de ilgili register'lardan yazma izin bitlerinin 1 yapılması gerekiyor olabilir. Hatta sanırım config bitleri ile bile ilgisi var.
Tavsiyem Arr1[0] = 0xff00; satırının oluşturduğu asm koduna bakman yönünde. O zaman neyin eksik yapıldığını anlamak mümkün olabilir.
C18 rehberinde şöyle yazmış:
Alıntı YapWhen writing to a rom variable, the compiler uses a TBLWT instruction; however, there may be additional application code that needs to be written based on the type of memory being utilized. See the data sheet for more information.
Alıntı yapılan: Tagli - 03 Mart 2013, 08:44:35
C'de normal bir değişkene erişilebildiği gibi flash hafızasına da erişilebiliyor olması lazım. Yani Arr1[0] = 0xff00; gibi bir satırı yazabiliyor olman lazım. Okumada zaten sorun çıkmaz. Ancak yazma işlemi biraz daha karmaşık, bloklar halinde yapılması gerekiyor. Derleyici bu işi kendisi hallediyor olabilir ama yine de ilgili register'lardan yazma izin bitlerinin 1 yapılması gerekiyor olabilir. Hatta sanırım config bitleri ile bile ilgisi var.
Tavsiyem Arr1[0] = 0xff00; satırının oluşturduğu asm koduna bakman yönünde. O zaman neyin eksik yapıldığını anlamak mümkün olabilir.
C18 rehberinde şöyle yazmış:
Hocam mesela CCS C de rom pointer'ların işlenmesi derleyici tarafından gerçekleştiriliyor. C18'de bu özellik olmayabilir...
En basit yöntem o kısımları ASM kod bloklarıyla gerçekleştirilebilir...
Dizi tanımını bir önceki mesajda belirttiğim gibi başta yapabildim. Sonra bir fonksiyona girip okumayı denediğimde değer yüklenmiyordu, bugün her nasıl oldu ise rom'da oluşturduğum dizinin istediğim indeksini okuyabiliyorum. Yazma ve okumada problem yok, hatta (beklenen olarak) çok boyutlu ve int gibi diziler de tanımlayabiliyorum. Yardım eden arkadaşlara gerçekten teşekkür ederim. Sağolsunlar.
Çalışan kod blokları şu şekilde;
//Prg başı
rom volatile unsigned int Arr[2][200][16] =
{0xFF0A,0b1011110101111110,3,748,4,9,2,1,9,5,2,2,3,4,5,6,
4,3,2,8,9,2 ,5,7,3,9,3,5,7,0,3,0,
4,7,9,2,1 ,3,747,0,4,8,9,3,41,7,8,0,
3,7,1 };
.
.
.
F1 ()
{
volatile unsigned int m;
volatile unsigned int i;
i = 2;
m = Arr[0][2][6];
m = Arr[0][2][i];
}
Alıntı yapılan: Tagli - 03 Mart 2013, 08:44:35
Derleyici bu işi kendisi hallediyor olabilir ama yine de ilgili register'lardan yazma izin bitlerinin 1 yapılması gerekiyor olabilir.
Hocam tam da tahmin ettiğiniz gibi gözüküyor. Aşağıda, disasm'den aldığım bir blok var.
186: m = Arr[0];
0392 0E01 MOVLW 0x1
0394 6EF6 MOVWF 0xff6, ACCESS
0396 0E01 MOVLW 0x1
0398 6EF7 MOVWF 0xff7, ACCESS
039A 0008 TBLRD*
039C 50F5 MOVF 0xff5, W, ACCESS
039E 6EDF MOVWF 0xfdf, ACCESS
187: m = Arr[1];
03A0 0E02 MOVLW 0x2
03A2 6EF6 MOVWF 0xff6, ACCESS
03A4 0E01 MOVLW 0x1
03A6 6EF7 MOVWF 0xff7, ACCESS
03A8 0008 TBLRD*
03AA 50F5 MOVF 0xff5, W, ACCESS
03AC 6EDF MOVWF 0xfdf, ACCESS
188: m = Arr[3];
03AE 0E04 MOVLW 0x4
03B0 6EF6 MOVWF 0xff6, ACCESS
03B2 0E01 MOVLW 0x1
03B4 6EF7 MOVWF 0xff7, ACCESS
03B6 0008 TBLRD*
03B8 50F5 MOVF 0xff5, W, ACCESS
03BA 6EDF MOVWF 0xfdf, ACCESS
189:
Rom kullanmamın, flash işgal etmek ve okurken önemsenmeyebilir bir gecikme oluşturması dışında bir dezavantajı yok sanırım. Yukarıdaki asm bloğunda da görüldüğü gibi, okurkan 12 cycle bir gecikme oluşuyor. Bu da belki derleyici veya optimizasyon ayarına bağlı olarak dahi değişebilecek, çok da önemli olmayan bir gecikme.
Fkarizmatik hocam, 2k ram kullanıyorum, onu da linkerde birleştirdim zaten.
Merhabalar,
Konu eski ama konuyla ilgili sorum var, değişkeni rom olarak tanımladığımızda değişkene değer atandığında da derleyici, program hafızasındaki bölgeye yazmaları hallediyor görünüyor. ASM çıktısında WRITE_PROGRAM_MEMORY.P2 bölümü bu işi yapıyor olmalı.
Bu mekanizma problemsiz çalışıyorsa eğer, WRITE_PROGRAM_MEMORY.P2 fonksiyonunun içinde, yazılacak sektörü ram bufferına alıp gerekli değişikliği yaptıktan sonra flash bölgesine yazan bir kod var sanıyorum, doğru mu?
Normalde flasha yazmalar genellikle sıkıntılıdır, CCS bu konuyu rom ile çözmüş mü yoksa bana mı öyle geliyor?
Test kodu
#include <18LF14K50.h>
int32 rom var = 0x123456;
void func()
{
int32 a = var;
a++;
var = a;
}
void main()
{
while(TRUE)
{
func();
}
}
ROM used: 254 bytes (2%)
Largest free fragment is 16130
RAM used: 4 (1%) at main() level
15 (2%) worst case
Stack used: 1 locations
Stack size: 31
0000: GOTO MAIN
.................... #include <main.h>
.................... #include <18LF14K50.h>
.................... //////////// Standard Header file for the PIC18LF14K50 device ////////////////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996, 2014 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... #device PIC18LF14K50
0004: MOVFF @READ_PROGRAM_MEMORY.P2+1,01
0008: MOVFF @READ_PROGRAM_MEMORY.P2,00
000C: TSTFSZ @READ_PROGRAM_MEMORY.P2
000E: INCF @01,F
0010: TBLRD*+
0012: MOVFF TABLAT,POSTINC0
0016: DECFSZ @00,F
0018: GOTO 0010
001C: DECFSZ @01,F
001E: GOTO 0010
0022: CLRF TBLPTRU
0024: GOTO 00B2 (RETURN)
0028: MOVF INTCON,W
002A: MOVWF @03
002C: BCF INTCON.GIEH
002E: BSF EECON1.EEPGD
0030: BSF EECON1.WREN
0032: MOVLB F
0034: MOVLW 55
0036: MOVWF EECON2
0038: MOVLW AA
003A: MOVWF EECON2
003C: BSF EECON1.WR
003E: NOP
0040: MOVF @03,W
0042: IORWF INTCON,F
0044: MOVLB 0
0046: RETURN 0
0048: BCF EECON1.CFGS
004A: MOVF TBLPTRL,W
004C: ANDLW 0F
004E: MOVWF @00
0050: MOVLW F0
0052: ANDWF TBLPTRL,F
0054: TBLRD*-
0056: MOVFF @WRITE_PROGRAM_MEMORY.P2,01
005A: TSTFSZ @00
005C: BRA 006E
005E: MOVF TBLPTRL,W
0060: ADDLW 01
0062: ANDLW 3F
0064: BNZ 006E
0066: BSF EECON1.FREE
0068: TBLRD*+
006A: RCALL 0028
006C: TBLRD*-
006E: TSTFSZ @00
0070: BRA 0080
0072: MOVFF POSTINC0,TABLAT
0076: MOVF @01,F
0078: BZ 0082
007A: TBLWT+*
007C: DECF @01,F
007E: BRA 0086
0080: DECF @00,F
0082: TBLRD+*
0084: TBLWT*
0086: MOVLW 0F
0088: ANDWF TBLPTRL,W
008A: XORLW 0F
008C: BNZ 005A
008E: RCALL 0028
0090: TSTFSZ @01
0092: BRA 005A
0094: CLRF TBLPTRU
0096: GOTO 00D8 (RETURN)
....................
.................... #list
....................
....................
....................
....................
.................... int32 rom var = 0x123456;
....................
.................... void func()
009A: CLRF TBLPTRU
009C: MOVLW 3F
009E: MOVWF TBLPTRH
00A0: MOVLW FC
00A2: MOVWF TBLPTRL
00A4: CLRF FSR0H
00A6: MOVLW a
00A8: MOVWF FSR0L
00AA: CLRF @READ_PROGRAM_MEMORY.P2+1
00AC: MOVLW 04
00AE: MOVWF @READ_PROGRAM_MEMORY.P2
00B0: BRA 0004
.................... {
.................... int32 a = var;
.................... a++;
00B2: MOVLW 01
00B4: ADDWF a,F
00B6: BTFSC STATUS.C
00B8: INCF a+1,F
00BA: BTFSC STATUS.Z
00BC: INCF a+2,F
00BE: BTFSC STATUS.Z
00C0: INCF a+3,F
.................... var = a;
00C2: CLRF TBLPTRU
00C4: MOVLW 3F
00C6: MOVWF TBLPTRH
00C8: MOVLW FC
00CA: MOVWF TBLPTRL
00CC: CLRF FSR0H
00CE: MOVLW a
00D0: MOVWF FSR0L
00D2: MOVLW 04
00D4: MOVWF @WRITE_PROGRAM_MEMORY.P2
00D6: BRA 0048
00D8: GOTO 00F6 (RETURN)
.................... }
....................
.................... void main()
00DC: CLRF TBLPTRU
00DE: BCF RCON.IPEN
00E0: MOVLW 00
00E2: MOVWF ANSEL
00E4: BCF ADCON1.NVCFG0
00E6: BCF ADCON1.NVCFG1
00E8: BCF ADCON1.PVCFG0
00EA: BCF ADCON1.PVCFG1
00EC: MOVWF ANSELH
00EE: CLRF CM2CON1
00F0: CLRF CM2CON0
00F2: CLRF CM1CON0
.................... {
.................... while(TRUE)
.................... {
.................... func();
00F4: BRA 009A
00F6: BRA 00F4
.................... }
.................... }
00F8: SLEEP
Configuration Fuses:
Word 1: FF38 CPUDIV4 USBDIV2 PLLEN PCLKEN FCMEN IESO
Word 2: 1E1E PUT BROWNOUT BORV19 NOWDT WDT32768
Word 3: 8800 HFOFST MCLR
Word 4: 0089 STVREN NOLVP BBSIZ2K NOXINST NODEBUG
Word 5: C003 NOPROTECT NOCPB NOCPD
Word 6: E003 NOWRT NOWRTC NOWRTB NOWRTD
Word 7: 4003 NOEBTR NOEBTRB
ROM data:
003FFC: 56 34 12 00 V4..