PIC32 Flash write sorunsalı

Başlatan hasankara, 25 Aralık 2014, 20:18:44

hasankara

PIC32MX denetleyicisi ile yaptığım çalışmada eeprom ihtiyacım oldu ve ne yazık ki eeprom bu seride bulunmuyor. Bu sebeple flash belleğinin kullanılmayan bir kısmını eeprom gibi kullanmaya karar verdim.

kısmen başarılı olabildim ancak hala problemim büyük sayılabilir;

Pic32mx için yayınlanan section 5. olan flash programming frm sinde flash üzerine veri yazmamızı sağlayacak c dilinde yazılmış fonksiyon örnekleri var. bu fonksiyonları kendi projemde kendim aynı şekilde yazdım ancak flash a veri yazma işini hiç bir şekilde bu fonksiyonlar yapamadı. Bu arada fonksiyonun adı NVMWriteWord.

Daha sonra pic32mx in plib i içinde bu fonksiyonların hali hazırda dahil edilmiş olduğunu fark ettim. Bu fonksiyonu kullandığımda belirttiğim adrese belirttiğim datayı bir kerelik yazıyor. bunu, pointer dan aynı adreste ki bilgiyi okuyarak görebiliyorum. ancak aynı adrese tekrar başka bir bilgi yüklemek istediğim zaman bu işlem başarılı olamıyor. ve yazmak istediğim data çok farklı olmasına rağmen ikinci yazışımın karşılığında okuduğum hep 2 sayısal değeri oluyor. sonraki yazma işlemlerinin sonunda yaptığım okumalarda ise sürekli 0 sayısal değeri görülüyor. buraya kadar hep aynı adres üzerinde yaptığım denemelerdi.

bir sonraki denemem ise aynı adrese bir kez veri yazıp bir sonraki adrese 1 er artan sayısal değerleri 1 er saniyelik aralıklarla yazma şeklinde oldu. Bu işlem sorunsuz tamamlandı. programı çalıştırdıktan bir süre sonra çip içinden program belleği okuduğumda da birer artan sayısal değerleri sırasıyla hex içinde görebildim. her şey olağandı.

özetle reset atmadığım sürece program hafızasının aynı adresine birden fazla kez veri yazma işlemini gerçekleştiremiyorum. reset attıktan sonra aynı adrese yine veri 1 kez yazılabiliyor.

ihtiyaç olabilir düşüncesi ile ikinci deneme kodumu paylaşayım;
not.: değişkenler static olup ds6 değerinin içeriği başka bir task ta lcd de incelendi.
addr = 0x9D01062C;
        p = (void*) addr;
        ds6 = *p;
        mlt_delay(1000); // 1 sn bekleme
        while (1) {
            mlt_delay(1000); // 1 sn bekleme
            addr += 4;
            p = (void*) addr;
            ds6++;
            NVMWriteWord((void*) addr, ds6); // hafiza = ds6
            ds6 = *p; // ds6 = hafiza
        }


frm section 5 incelemek için http://ww1.microchip.com/downloads/en/DeviceDoc/61121F.pdf linkini kullanabilirsiniz.

- flash a program yazma işini daha önce yapmış olanlarımız vardır ümidi ile yazmak istedim.
- kafamdaki diğer soru ise; manual da verilmiş olan fonksiyonun çalışmıyor olması ile yine kendi kütüphanesindeki fonksiyonun çalışıyor olması.

leblebitozu

Yazmadan önce NVMErasePage fonksiyonu ile ilgili page'i silmen gerekir, yoksa tekrar yazma yapamazsın.

hasankara

Evet çok teşekkür ediyorum şu an aynı adrese veri yazabiliyorum. ancak erase page birden fazla adres mi siliyor acaba? ve erase page de bayağı bir vakit kaybı oluşuyor.

şimdi denedim ki evet 2. denemem için while içine erase page ekleyerek sırayla adresi arttırdığımda okuduğum hex de en son saydığı sayıyı yazıyor önceki yazdıkları ise tekrar ff lerle dolmuş. muhtemelen her erase page dediğinde önceki adresleride siliyor. erase word de olsaymış güzel olurdu.

leblebitozu

ErasePage 4K'lık bölümü direk siliyor bildiğim kadarıyla, eski verileri ram'e alıp tekrar yazmak gerekir.

hasankara

anladım teşekkürler. peki bir başka yolu yok mudur bu işin acaba?

Burak B

Hayır yok. Hatta tüm flashlar böyle çalışır.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

Muhittin22

#6
Bu konu epey eskimiş ama paylaşmakda fayda göryüyorum.
Kullandığım  PIC32MX150F128D. 32 bit işlemciler için.


Flash hafıza yapısı gereği, hafıza byte'lerini silinmiş hali Bin (11111111) Hex (FF) olur.
Yeni veri yazıldığında verinin sadece  "0" değerleri işlenir. "1" lere dokunulmaz. Bu nedenledir ki flash hafızaya bilgi yazılacaksa öncelikle hafıza silinmelidir. Hafıza silme işleminde byte'a erişilemediğinden bölge silme yöntemi kullanılıyor. Kitapçıklarda her bir silme işlemi için 4096 byte'lık blok silinir yazıyor, ama benim testlerim 2048 byte'ın üstüne çıkmadı.
PIC Flash hafıza, aynı zamanda program hafızası olduğu (Genellikle NVM_PROGRAM_PAGE 0xBD000000 adresinden başlar) silinecek ve yazılacak bilginin PIC in ana programına denk gelmemesi için, PIC in hafızasını kontrol ederek, geri kalan boş bölge adreslenmelidir.

Yazma işlemi her seferinde byte değil 32 bit long int (4 byte) olarak gerçekleşiyor. 

Yazma işlemi sırasında Genel interrupt 'in disable yapılması iyi sonuç veriyor. Çok hızlı yazdığı için önemli bir zaman kaybı olmuyor.

Aşağıda örnek bir kod verilmiştir.
This code is runing correct;
#define NVM_PROGRAM_PAGE 0xBD015000 // OK Bu kayıt için   "86016"  adres başlangıcı seçilmiştir.
flexible  to 0xBD01FFFF; 
//#define NVM_PAGE_SIZE 4096 yerine
unsigned long databuff[32]; ////OK !! (4 byte) X 32 = 128 byte


int write_example() {
unsigned int x1,i1,i2; //2 byte
unsigned long L0=0; //4 byte
x1=0;

i1=12345;
i2=16789;
LO=i1 << 16;
LO |= i2;

while(x1<32) { //Fulling 128 byte
databuff[x1]= LO;//OK long = 4 byte
x1++;
}

NVMErasePage((void *) NVM_PROGRAM_PAGE);//Bu komut 2048 byte siler.
NVMWriteRow((void* )NVM_PROGRAM_PAGE, (void* )databuff); //"NVMWriteRow" diye tanımlanan 128 byte yazar.
if(memcmp(databuff, (void *)NVM_PROGRAM_PAGE, sizeof(databuff)))
{

}
}