ibrahim ozturk

Entrepreneur, Tech CTO, Software Developer, Electronics Engineer, Author




STM32 lerde EEPROM Emulasyonu

Çok farklı tarzlarda birçok gömülü sistem mikroişlemci uygulaması güç kesildiğinde de kullanıcı ya da sistem tarafından değiştirilebilen ya da ayarlanabilen bir çok veriyi kaydetmek durumundadır. Bunun için ilk akla gelen çoğu mikokontrollerde bulunmayan harici bir EEPROM ile verilerin saklanmasıdır. Harici EEPROM (electrically erasable programmable read-only memory)  kullanmaktansa, STM32 serisindeki çoğu MCU’nun dahili Flash hafızasını kullanarak kalıcı veri saklama yapabildiğinizi biliyor muydunuz? Üstelik bu yöntemin harici EEPROM kullanmaya göre  yazma ve okuma sürelerinin oldukça hızlı olması gibi çok daha avantajlı tarafları da mevcuttur.”AN2594” kodlu “EEPROM emulation in STM32F10x microcontrollers” isimli eke linkini eklediğim Application notundaki Tablo 1’de ayrıntılı inceleyebilirsiniz. EEPROM emulation işlemini ilk defa gerçekleştirirken bazi noktalarda fazlaca zaman harcadiğimdan takip ettiğim tüm gerekli adımları. daha sonra benzer problemler yaşayanlara yardımcı olma adına buraya aktararak bir yazı oluşturmaya karar verdim. Sorularınızı, yasadığınız problemleri aşağıdaki yorum kısmından aktarmanızdan memnun olurum.

  • Neden ihtiyaç duydum?

Tasarladığım kartta her cihaz RS485 üzerinden haberleştiğinden her birinin en azından belirli ve ayarlanabilir Cihaz ID’lerinin olması gerekiyordu. Bu kadar kısıtlı miktarda bir veriyi saklamak için flasha yazma yerine OTP (one-time programmable) alanını ya da Back-Up Registers (BKP) birimini kullanabilir olsanız da ileride farklı parametre ekleme durumundan dolayı data hacmimin oldukça büyüyeceği bir senaryoda bu yöntemler işime pek de yaramayacaktı. Dolayısıyla, bu işlemi de asgari maliyette yani harici bir EEPROM ilave etmeden, hem de daha optimum bir şekilde çözmenin yollarını ararken bu yönteme başvurdum ve ayrıntılarını sizinle paylaşmak istedim.

  • Kullanılan ortam bilgileri

Kullandığım ve test ettiğim MCU : STM32F100C8 (stm32vldiscovery board undaki MCU ile flash büyüklüğü hariç hemen hemen aynı özelliklere sahip bir mikrokontroller). Buna paralel olarak, flash adres ayarlamaları STM32F10x serisindeki orta ölçekli (32 ve 128 Kbyte arasında) flash büyüklüğüne sahip mikrokontrollerlara uygun olarak düşünülmüştür.

Kullandığım ve test ettiğim IDE: Keil MDK uVision 4

  • Flash Adres Ayarlamaları
#define BANK1_WRITE_START_ADDR ((uint32_t)0x08000400)
#define BANK1_WRITE_END_ADDR ((uint32_t)0x08003000)

#define FLASH_PAGE_SIZE    ((uint16_t)0x400)
  • Linker Script düzenlemesi

STM32 bünyesinde herhangi bir MCU’da yazmış olduğunuz kodu çok farklı flash ve RAM büyüklüklerine ve adreslemelerine sahip MCU da çalıştırılabilir hale getiren nedir acaba? İşte bu aşamada, gömülü bağlayıcı kodu olarak da Türkçeye çevrilen Linker Scripts, derleyici tarafından oluşturulan ara kodları işletim sisteminin çalıştırabileceği makine kodlarına (.hex hex dosyası gibi) çeviren kod parçacığı devreye girmektedir. Linker ayarlamaları bağlamında kullanacağınız önemli noktalardan biri olan Scatter dosyasında, memory bölgelerini, adreslemelerini, heap/stack bölgesini, heap/stack büyüklüğünü ve RAM, ROM bölgelerinin kullanım taslağını tanımlama gibi imkânlara sahipsiniz.  Bu genel bilgilendirmenin ardından, EEPROM emulasyonu surecinde yapılması gereken scatter dosyasındaki düzenlemeleri manüel ve otomatik olarak yapmanın yolunu su şekilde özet geçebiliriz.

Arayüz aracılığı ile flash data adres düzenlemesi:

EEPROM_Emulation_AddressConfiguration

EEPROM Emulation Address Configuration

Manual olarak flash data adres düzenlemesi:

Öncelikle manual kullanacağınızı buradan scatter dosyanızı göstererek seçiyorsunuz:

Scatter Dosyasi Ekleme

Scatter Dosyasi Ekleme

Scatter dosyası içeriği :

Scatter Dosyasi İçerik Düzenlemesi

Scatter Dosyasi İçerik Düzenlemesi

  • Flash Okuma-Yazma Addressleri
#define BANK1_WRITE_START_ADDR ((uint32_t)0x08000400)
#define BANK1_WRITE_END_ADDR ((uint32_t)0x08003000)
#define FLASH_PAGE_SIZE    ((uint16_t)0x400)
  • Flash’dan Okuma
uint32_t EEPROM_Read(void)
{
uint32_t readValue;
FLASH_UnlockBank1();
Address = BANK1_WRITE_START_ADDR;
readValue = (*(__IO uint32_t*) Address);
FLASH_LockBank1();
return readValue;
}
  • Flash’a Yazma
void EEPROM_Write(uint32_t Data)
{
//FLASH Bank1 Programlanmasi
//Flash Bank1 Programlamak icin kilidin kaldirilmasi
FLASH_UnlockBank1();
//İlgili bank da bulunan sayfa sayisini hesaplama
NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE;
//Ilgili tum bayraklarin temizlenmesi
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
//Flash sayfalarinin silinmesi
for(EraseCounter=0; EraseCounter<NbrOfPage; EraseCounter++)
{
FLASHStatus = FLASH_ErasePage(BANK1_WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
if (FLASHStatus != FLASH_COMPLETE)
break;
}
//Flash Bank1 Programlanmasi
Address = BANK1_WRITE_START_ADDR;
while((Address < BANK1_WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))
{
FLASHStatus = FLASH_ProgramWord(Address, Data);
Address = Address + 4;
}
FLASH_LockBank1();
//Yazilan datanin dogrulugunun kontrol edilmesi
Address = BANK1_WRITE_START_ADDR;
while((Address < BANK1_WRITE_END_ADDR) && (MemoryProgramStatus != FAILED))
{
if((*(__IO uint32_t*) Address) != Data)
{
MemoryProgramStatus = FAILED;
}
Address += 4;
}
}

Dataların güvenli bir şekilde belirtilen adreslere yazıldığını STLink Utility den ekran vererek göstermeyi ve kisa bir video ile çalışan halinin videosunu eklemeyi en kısa zamanda yapmaya çalışacağım.

  • Kaynaklar

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00165693.pdf

İbrahim Öztürk / Elektronik Mühendisi / York – UK
www.ozturkibrahim.com
[email protected]

SHARE :

(2) comments

Doğukan
4 sene ago · Cevapla

Hocam FLASH_UnlockBank1() fonksiyonu hata veriyor keil uvision 5 te

    Administrator
    4 sene ago · Cevapla

    Nasil bir hata veriyor?

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*


error: Content is protected !!