[Çözüldü] STM32 GCC'de Spesifik Alanda Değişken Tanımlama

Başlatan MrDarK, 12 Mayıs 2015, 12:06:15

MrDarK

Arkadaşlar merhaba ;

STM32'yi Emblock ve GCC ikilisi ile kullanmaktayım. Yapmak istediğim şey SRAM içinde bir alanı RAM'den ayırarak compiler'ın kullanımından çıkartmak ve yazılım içinde de bu çıkarttığım alanı güvenli bir şekilde kullanmak.

İşlemciye system reset attırdığımda RAM'in o bölgesini sıfırlamak istemiyorum, rtc backup registerlarını da tamper algılandığını anda sıfırlandığı için kullanamıyorum. Daha önce bu şekilde bir işlem yapan var mı ?

Sanırım sorumun bir kısmı buradaki başlıkta var ; https://www.picproje.org/index.php/topic,53804.msg409314.html#msg409314

Fakat startup dosyasında
    /* Zero fill the bss segment. */
    ldr   r1, = __bss_start__
    ldr   r2, = __bss_end__
    movs  r3, #0
    b  .fill_zero_bss
.loop_zero_bss:
    str  r3, [r1], #4

.fill_zero_bss:
    cmp  r1, r2
    bcc  .loop_zero_bss


Bu şekilde bir alan var bütün RAM belleği sıfıra çeken, burada anladığım __bss_start__ bilgisini nereden çekiyor RAM yazan adresin başlangıcını mi kullanıyor ? herhangi böyle bir #define görmedim
Picproje Eğitim Gönüllüleri ~ MrDarK

Gökhan BEKEN

#1
Hangi sram bu, stm32f429 discovery'deki sram'den bahsediyorsan kullanmıştım, hazır örnekleri var st'nin. Bir pointer tanımlayıp, adres olarak örnekteki adresi veriyorsun, artık rahatça kullanıyorsun. Reset olduğunda ne olduğunu hiç denemedim.

Düzeltme: yukarıdaki yazdıklarımda yanlışlık var, SDRAM yerine SRAM demişim.
Özel mesaj okumuyorum, lütfen göndermeyin.

mufitsozen

Sayin @MrDark, benim bildigim kadari ile istediginiz islem gcc'de  iki asamada yapilabilir:

1- c programinizda (yanlis hatirlamiyorsam) __attribute__ komutlari ile 'section'(lar) tanimlamaniz lazim, sonrada linker konfigurasyon dosyasinda bu 'section'(lar)in 'absolute address'lerini tanimlamak.

Su anda atolyemden uzakta oldugum icin notlarim yanimda degil. Ama internetde bu sekilde bakarsaniz oldukca cok ornek bulabileceksiniz.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

MrDarK

#3
Gökhan o değişkeni compilerın kullanmaması için __bss_start__'dan kaldırmam lazım ;

Normal işlemcinin RAM alanı içindeki bi yerden kendime parça almak istiyorum 20 word kadar :) fakat compilerdan da çıkartsın istiyorum. Reset olduğunda eğer MEMORY kısmındaki __bss_start__ 'dan çıkartamazsam tüm RAM alanı sıfırlanacak ki bu benim istemediğim birşey :)

@mufitsozen hocam teşekkür ederim;

Konu içine koyduğum linkte biraz anlatmış dediğiniz gibi işlem yapılmış aslında merak ettiğim o şekilde kullandığımda __bss_start__ 'dan çıkmış oluyor mu. Birde aynı linkteki örnekte @AsHeS hocam
Aşağıya
  .RAMzios : {*(.RAMzios)} > ZIOS_RAM_SECTION
yazın.

bu şekilde eklemiş; bunu yazmak yetiyor sanırım değil mi ?

Bu arada isimleri değiştiricem tabiki :)
Picproje Eğitim Gönüllüleri ~ MrDarK

mufitsozen

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

tw0_p1ch

#5
Paylasiminiz  ve deneyimleriniz icin tesekkurler
KubilAY

yamak

Hocam eğer verileri değişken tanımlarak RAM e yazacaksanız linker file'dan kendiniz bi section tanımlamanız gerekir.Eğer değişken ismi tanımlamak gerekmiyosa:
RAM in kullanılmayan bi bölgesine pointer aracılığıyla yazabilirsiniz.bss_segment+data_segment+stack+heap i hesaplayıp arda kalan herhangi biyere yazabilirsiniz.

MrDarK

#7
yamak , mufitsozen , AsHes hocalarım ;

Öncelikle hepinize teşekkür ederim. İstediğim uygulama çalıştı. Kullandığım işlemcinin flash.ld ve sram.ld dosyalarına section olarak ekleme yaptım. RAM Değerim 32K idi bu durumda ;

.ld dosyalarını şu şekilde kurguladım;

/* Memory Spaces Definitions */
MEMORY
{
    ROM  (rx)               : ORIGIN = 0x08000000, LENGTH = 128K
    RAM (rwx)               : ORIGIN = 0x20000000, LENGTH = 31K
    EXT_RAM_SECTION (rw)    : ORIGIN = 0x20007C00, LENGTH = 1K
}

    .RAMext :
    {
        *(.RAMext)
    } > EXT_RAM_SECTION


Sonrada yazılım içindeki herhangi bir .c dosyasında şu tanımlamayı yaptım;

uint32_t Ext_Ram_Array[250] __attribute__((section(".RAMext")));


Bu sayede reset atıldığında silinmeyen bir dizim oldu. Test etmek için derleme yaptıktan sonra değişkenin adresini kontrol etmenizi öneririm. Benimkisi yukarıdaki tanımlamalara göre 0x20007C00 adresinden başlıyor. __bss_start__ __bss_end__ aralığından çıktığına inanıyorum çünkü onları 31K yazarak sınırladığımı düşünüyorum. Hatalıysam söylerseniz sevinirim.

Dipnot : Değişikliği yaptıktan sonra mutlaka Rebuild All diyerek kodu yeniden derleyiniz. Yoksa derleyici kod güncel diyebiliyor.
Picproje Eğitim Gönüllüleri ~ MrDarK

mufitsozen

Alıntı yapılan: MrDarK - 12 Mayıs 2015, 13:53:07

Bu sayede reset atıldığında silinmeyen bir dizim oldu. Test etmek için derleme yaptıktan sonra değişkenin adresini kontrol etmenizi öneririm. Benimkisi yukarıdaki tanımlamalara göre 0x20007C00 adresinden başlıyor. __bss_start__ __bss_end__ aralığından çıktığına inanıyorum çünkü onları 31K yazarak sınırladığımı düşünüyorum. Hatalıysam söylerseniz sevinirim.


Onu sen bize soyleyeceksin
Linkerin MAP outputunda her segmentin yeri ve boyu listelenir
Bu sekilde bir degisiklik yapip normalin disina cikinca MUHAKKAK linker MAPden kontrol etmelisin

Gecmis olsun
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

MrDarK

Map dosyasını incelediğimde ;

Memory Configuration

Name             Origin             Length             Attributes
ROM              0x08000000         0x00020000         xr
RAM              0x20000000         0x00007c00         xrw
EXT_RAM_SECTION  0x20007c00         0x00000400         rw
*default*        0x00000000         0xffffffff

.bss            0x20000388     0x2778 load address 0x08016830
                0x20000388                __bss_start__ = .
                0x20002b00                __bss_end__ = .


Şeklinde görünüyor ; bu durumda 0x20007c00 adreslemesi ile bss start end arasından kurtulduğum kesinleşmiş oluyor :) Mufit hocam kesinleştirdiğiniz için teşekkürler :)
Picproje Eğitim Gönüllüleri ~ MrDarK