7

STM32-Flash Hafızaya Veri Yazma ve Okuma

Bazı Gömülü Sistem projelerinde kullanıcı tarafından değiştirilen bir değere (kullanıcı adı,şifre vb.), sistemin enerjisi kesilip tekrar geldiğinde veya sistem resetlendiğinde tekrar erişmek gerekebiliyor. Böyle durumlarda mikrodenetleyicinin programcılar için ayrılan adreslerine veri yazılıp ve gerektiğinde o adrese erişerek veriler çekilebilir. Flash hafızanın bir yazma sınırı olduğunu unutmayalım. Yani sürekli flash hafızaya veri yazılıp okunduğu bir uygulama önerilmemektedir. Bu yazıda STM32F1 serisi için Flash Hafızaya veri yazma veya Flash Hafızadan veri okuma işleminin bir örnek uygulamasından bahsedeceğim.
Öncelikle STM32f1 de flash adrese veri yazma ve okuma işlemi 16 bitlik(half-word) değişkenler ile yapılır. İlk olarak en basit olanından yani veri okuma fonksiyonundan başlayalım. Aşağıda görüldüğü gibi bu fonksiyon iki satırdan oluşmaktadır. C programlamadan hatırlayacağınız üzere pointerlar ile adrese erişip adresteki veriyi alma mantığına dayanır.

Flash adrese veri yazmak ve flash adresteki veriyi silmek , okumaya göre biraz daha farklıdır. STM32 de bu işlemleri yapabilmek için öncelikle flash kilidini açmak gerekir. Bunun için STM32 programming manualden  yararlanabiliriz. Flash kilidini açmak için FLASH->KEYR registerına programming manualdeki key1 ve key2 sırası ile gönderilmelidir. Böylece flash kilidi açılmış olur. Yazma veya silme işlemi bittikten sonra FLASH_CR registerı resetlendiği zaman flash tekrar kilitlenmiş olur ve yazma,silme işlemi yapılamaz. Aşağıda programming manuel den alınan flash key değerlerine ait değerler verilmiştir.

STM32f1 Flash Keys

Flash Keys

Peki hangi adrese veri yazacağız. Bunu da yine programming manual veya reference manual’deki “flash memory map” tablosundan bulabiliriz. Aşağıda bu tablo verilmiştir.

stm32 flash memory map

STM32F1 Memory Map

Dikkat edilirse main memory 128 adet 1 kbyte’lık sayfalardan oluşmaktadır. Burada önemli bir noktaya değinmek gerekir. Yazma işlemi yapılırken tek bir adrese yazılır fakat silme işlemi tüm sayfayı siler.

Yukarıda yazma ve silme işlemleri için yazılan fonksiyonlar verilmiştir. Aşağıdaki kodda dikkat edilirse yazma adresi olarak Page 127‘nin başlangıç adresi seçilmiştir.

Kod yüklendikten sonra değişkenlerdeki değişimleri STMStudio ile izleyebilirsiniz.

Read_Flash Öncesi

Read_Flash Sonrası

Kodların Tamamı

 HAL Kütüphanesi ile Flash Hafıza Örneği

Bir örnekte HAL kütüphanesi ile yapalım. Bu örnekte silme işlemi ile yazma işlemini tek bir fonksiyon içerisinde yapacağız. Silme işlemi bir kaç satırdan oluştuğu için aynı fonksiyon içinde aşağıdaki gibi kullanabiliriz.

Bu fonksiyon içerisinde HAL_FLASH_Program() fonksiyonu ile istersek 32 bit veya 64 bitlik değerleri hafızaya yazabiliriz. Tabi arka planda değerler yine 16 bit olarak hafızaya yazılır. HAL_FLASHx_Erase() fonskiyonu bizden bir hata parametresi bekler. Eğer silme işleminde hata oluşur ise bu parametreye girilen değişkeni hangi adresi silerken hata oluştu ise o adresin değerine eşitler.

NOT: Ben bu örneği STM32F103C8T6(Blue Pill) üzerinde denedim. Yazının başında verdiğim tabloda STM32F1 serisinin Memory Map tablosunda 128 sayfa olduğu görülmektedir fakat her f1 modeli 128 sayfalık yani 128 kb flash hafızaya sahip değildir. STM32F103C8T6 da C den sonra gelen 8 kodu 64 kb lık bir flash hafızaya sahip olduğunu belirtmektedir.

Memory Map tablosunda 63. sayfanın hangi adreste olduğu yazmamaktadır. Peki herhangi bir sayfanın adresini nasıl hesaplayabiliriz? Bunu basitçe aşağıdaki gibi hesaplayabiliriz.

Memory map’ten page 0′ ın başlangıç adresini ve her sayfanın 1 kb(1024 byte) olduğunu biliyoruz. Buna göre istenilen sayfanın başlangıç adresini yukarıdaki gibi hesaplayabiliriz.

Kaynak: http://www.picproje.org/

Mehmet Topuz

Mehmet Topuz

7 Comments

    • Evet doğrudur. Flash hafızanın boş olduğu durum 0xFF değeridir. Aynı zamanda hafızadan veri silindiğinde değeri 0xFF olmalıdır.

  1. Mehmet bey merhabalar, öncelikle verdiğiniz bilgiler için teşekkür ederim. Takıldığım bir nokta var. STM32F103CBT6 kodlu işlemci kullanıyorum. Float değerim var ve flash hafızaya kaydetmek istiyorum. Nasıl bir yol izleyebilirim?

    • Merhaba, rica ederim. Öncelikle float 32 bitlik bir değişkendir. Flash hafızaya yazarken 16 bitlik değerler yazabiliyoruz. Float değişkenlerde bit kaydırma işlemi(<<) yapılmadığı için float değişkeni 16 bitlik iki değişkene parçalamak zor bir iş. Bunun yerine float değişkenin virgülden sonraki basamağını sabit kabul ederek virgülden önceki ve virgülden sonraki sayıyı iki ayrı 16 bitlik değişkene atayıp hafızaya kaydedebilirsin. Örneğin; Float değişkeni şöyle iki değişkene atayabilirsin.

      float a = 13.35;

      uint16_t b = a;    // b = 13

      uint16_t c = a*100;

      c = c%100;        // c = 35

      Burada değişkenin birini örnek olarak 0x0801FC00 adresine diğerini ise 0x0801FC02 adresine kaydedebilirsin. Daha sonra bu adreslerden veri okuduktan sonra tekrar bu iki sayıyı float tipine dönüştürmek istiyorsan bunu da şu şekilde yapabilirsin.

      float d = b;         // d = 13.0

      d = d+ (float)c/100; // d = 13.35000

      Bunu böyle bir deneyiniz. Eğer kod çalışırsa buraya tekrar yazarsanız sevinirim. Sonucu ben de merak ediyorum.

  2. Sorunumu şu şekilde çözüme ulaştırdım. Belki ihtiyacı olan arkadaşlar olabilir;
    typedef union
    {
    uint16_t dataBytes[2];
    float f;
    }floatToChar_t ;

    fonksiyon olarak kullanımı;
    Write_Flash(carpanDegeriAdress, degisken.dataBytes[0]);
    Write_Flash(carpanDegeriAdress1, degisken.dataBytes[1]);

    ve;
    degisken.dataBytes[0] = Read_Flash(carpanDegeriAdress);
    degisken.dataBytes[1] = Read_Flash(carpanDegeriAdress1);

    şeklinde. (Read_Flash ve Write_Flash fonksiyonları sizin yukarıda yazmış olduğunuz fonksiyonlar.)

  3. İşlemler bittikten sonra Flash_Lock komutunun önemi nedir?
    Resetten sonra flash’ı unlock etsek ve bir daha hiç Lock etmesek, veri kaybı yaşar mıyız? Veya veri kaybı yaşama olasılığımız ne oranda etkilenir?

    • Bu komut sadece flasha yazmayı engeller. Genelde yanlışlıkla program kodları değiştirilmesin diye kullanılır. Mikrodenetleyici üzerinde çalışan kodlar da flash hafızda tutulur. Bu kodlardan herhangi bir byte silinse mikrodenetleyicide bir süre sonra hata oluşur. Bunun önüne geçmek için konulmuş bir önlem olabilir. Flashı lock etmesende bir sıkıntı çıkacağını zannetmiyorum program hafızasına veri yazmadığın sürece tabi. Mikrodenetleyici resetlendiğinde tekrar otomatik kilitlenecektir.

Bir cevap yazın

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