PIC Hafıza problemi

Başlatan mesmert, 04 Mayıs 2011, 00:57:48

mesmert

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.

Tagli

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.
Gökçe Tağlıoğlu

FEHMİ_ASM

#2
   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.
Hz.Hamza'nın Belinde İki Kılıç Duruyor ! Attığı Her Adım Bir Kalbi Durduruyor ! Ey Hamza ! Gördüğün Hiçbir Şeyden Korkmazsın , Bu Doğru Ama Heybetini Gizli Tut , Yürüyüşün Ölümü Korkutuyor !  İşte Hz.Ömer ve Hz.Ali , Biri Hattaboğlu , Biri Haydâr-ı Kerrar ! Ve Kolkola Ölümün Ağzına Giriyorlar !  Azrai

fatih6761

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.

FEHMİ_ASM

   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};
Hz.Hamza'nın Belinde İki Kılıç Duruyor ! Attığı Her Adım Bir Kalbi Durduruyor ! Ey Hamza ! Gördüğün Hiçbir Şeyden Korkmazsın , Bu Doğru Ama Heybetini Gizli Tut , Yürüyüşün Ölümü Korkutuyor !  İşte Hz.Ömer ve Hz.Ali , Biri Hattaboğlu , Biri Haydâr-ı Kerrar ! Ve Kolkola Ölümün Ağzına Giriyorlar !  Azrai

Mr.Java

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.

Tagli

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.
Gökçe Tağlıoğlu

fatih6761

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...

FEHMİ_ASM

#8
   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.


   
     
Hz.Hamza'nın Belinde İki Kılıç Duruyor ! Attığı Her Adım Bir Kalbi Durduruyor ! Ey Hamza ! Gördüğün Hiçbir Şeyden Korkmazsın , Bu Doğru Ama Heybetini Gizli Tut , Yürüyüşün Ölümü Korkutuyor !  İşte Hz.Ömer ve Hz.Ali , Biri Hattaboğlu , Biri Haydâr-ı Kerrar ! Ve Kolkola Ölümün Ağzına Giriyorlar !  Azrai

SpeedyX

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..