Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Konuyu başlatan: e-zeki - 23 Ekim 2019, 17:25:27

Başlık: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 23 Ekim 2019, 17:25:27
Merhabalar,
vakti zamanında bir harici bootloader yapmıştım. Flash memory'de 2 farklı proje olarak gayet güzel çalışıyor. Fakat 2. proje ortadan kalksın (Ana hex'i silip yenisini yazan kısım), bootlayıcı hex cihaza yüklendi mi yüklenmedi mi yüklenmediyse ne yapacağız derdi ortadan kalksın isteniyor.
Alternatif olarak da;  bootlayıcı kod bloğunu, cihaz çalışırken ram'a aktarıp ram'de koşturalım, o koşarken ana hex bloğunu flash memory'den silsin ve yenisini yükleyip cihazı resetlesin.

Sorun şu ki fonksiyon ram'e taşınıyor fakat ana hex bloğunda silme yaptığım an işlemci ölüyor.

bir kod bloğunu ram'de sorunsuz koşturmanın bir yolu var mıdır? böyle bir şeyle uğraşan oldu mu daha önce?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: OptimusPrime - 23 Ekim 2019, 18:07:26
Derleyicinin kullanma klavuzuna bakmak lazim. Gorunuse gore ram a tasinan fonksiyonun bir kismi hala flash da. Aslinda bu durumda derleyici uyari vermeli. Birsey diyor mu?

Bu arada islemci oluyor derken, nasil oluyor? Nerede oldugunumu sapitiyor yoksa exception mi veriyor?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: z - 23 Ekim 2019, 19:57:16
0. sektoru siliyormusun?

Siliyorsan vektorleri rama yada silmedigin flash sektorlerine tasiyormusun?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 23 Ekim 2019, 21:38:42
@OptimusPrime hocam nerede olduğunu şaşırıyor. 0x00000000'a gidiyor. Derleyici hata vermiyor, herhangi bir uyarı ya da exception vermiyor.

@z hocam 0. sektörü siliyorum evet. SBC->VTOR ile yeni adres atadım fakat başka bir şey  yapmadım. hatta vector table'ı taşıyınca basit led blink bile çalışmadı. acaba RCC ve Init'leri de mi ram'a taşımam gerek?

bu arada projenin detaylarını da vereyim unutmuşum:
Keil uVision 5
stm32f103c8t6
Hal Library.

Not: Projeyi CubeMX ile oluşturdum fakat ram'a taşıdığım fonksiyonun tüm komutları register düzeyinde tanımlamalar. içerisinde hal'a özel ya da başka bir fonksiyona dallanma yok. 
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: yldzelektronik - 23 Ekim 2019, 21:40:05
Takipteyim. @e-zeki ramde çalışan bir kod örneği var mı? RAM'e taşırken derleyici ve/veya linker a özel bir bildiride bulunuyor musun?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 23 Ekim 2019, 21:49:24
@yldzelektronik hocam kopyalama işlemi basit bir memcpy ve fonksyion pointer'ı ile taşınabiliyor. iş yeri bilgisayarımda var fakat firma politikası gereği paylaşamıyorum yarın benzer birşey yazıp burada paylaşmaya çalışayım.
derleyiciye özel bir bildiirmde bulunmuorum. Projenin ilk halinde ROM bölgesini ve vector table adresini değiştirerek derliyordum. ama bunda çalışan projenin içerisinden bir fonksiyonu taşıdığım için derleme öncesi herhangi bir ön atama yapmadım. Bazı kaynaklar linker script içerisine bir takım eklemeler önermişler ama gördüğüm kadarıyla o önerilerin hepsi derleme esnasında ve runtime'ın başlangıcında kodu ram'de bir bölgeye çekmeyle ilgiliydi.Keil linker script kullanmadığı için işime de pek yaramadı derinlemesine incelemedim.
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: z - 24 Ekim 2019, 00:10:19
Alıntı yapılan: e-zeki - 23 Ekim 2019, 21:38:42@z hocam 0. sektörü siliyorum evet. SBC->VTOR ile yeni adres atadım fakat başka bir şey  yapmadım. hatta vector table'ı taşıyınca basit led blink bile çalışmadı. acaba RCC ve Init'leri de mi ram'a taşımam gerek?

Peki tablo icerigini dolduruyormusun?

Flashi silip Ram'e gectikten sonra kesinlikle reset yememen lazim. 

Bu yuzden sifiri silme. init rutinlerin vs 0 da kalsin. User programini 0 silindiginde silinmeyecek kadar uzak sektore yaz.

Yeni vektor tablosunun icini doldururken intlari yasaklaman gerek. Yada önce tablo oluştur sonra tablo adresini değiştir.

Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: OptimusPrime - 24 Ekim 2019, 02:12:38
Bu sekilde beslemen gitse bir daha boot edemiyorsun  ::op
Daha yakisikli bir cozum dusunmek lazim. Mesela ilk basta bootloader sonra en guncel programin en sondada yedegin gibi.
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 24 Ekim 2019, 08:54:25
@z
Alıntı yapılan: z - 24 Ekim 2019, 00:10:19Flashi silip Ram'e gectikten sonra kesinlikle reset yememen lazim.
Farkındayım. Söyledim de zaten. bootlama işlemi 1.5sn civarı sürüyor o yüzden bu riski alabiliriz denildi.

Alıntı yapılan: z - 24 Ekim 2019, 00:10:19Bu yuzden sifiri silme. init rutinlerin vs 0 da kalsin. User programini 0 silindiginde silinmeyecek kadar uzak sektore yaz.

Yeni vektor tablosunun icini doldururken intlari yasaklaman gerek. Yada önce tablo oluştur sonra tablo adresini değiştir.
Initleri yasaklayabilirim. Fakat tabloyu baştan oluşturma konusunda hiç bilgim yok nasıl yapabilirim?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 24 Ekim 2019, 08:57:13
@OptimusPrime

Alıntı yapılan: OptimusPrime - 24 Ekim 2019, 02:12:38Bu sekilde beslemen gitse bir daha boot edemiyorsun  ::op
Daha yakisikli bir cozum dusunmek lazim. Mesela ilk basta bootloader sonra en guncel programin en sondada yedegin gibi.
Hocam şuan çalışan yapı sizin dediğiniz gibi yakışıklı zaten  :D
tek fark Main -Bootloader - backup şeklinde. Burada sorun şu:
Bootloader başta olduğunda main bloğunun @z hocamın'da dediği gibi farklı rom adresinde derlenmesi gerek. projeyi yapan arkadaş bunu unutup hex oluşturduğunda facia oluyor. Bu sefer kontrolleri bootloader'da yapmaya başlıyorsunuz ve işler karışıyor. bootloader başlı başına bir kontrol mekanizması haline gelip genişlemeye başlıyor.
bootloader'ı ortaya koyarak küçük bir relocater haline getirdiğimizde ise stm32f4 mcu'ların(stm32f103'ü sadece test amaçlı kullanıyorum) flash memory sektörleri aşağı doğru gittikçe büyüyor. bootloader orta sektörlerden birine koyarsam 64kb'lık ya da 128kb lık bir sektörü kullanıma kapamış oluyorum bu da otomatikman benim güncelleme alanımın daralması demek zaten bundan kurtulmak istiyorum.

ha projeler 250-300kb oluyor mu derseniz şuan olmuyor ama projelerin genişleme hızına bakarak başımıza bela olmasın ileride diyerek böyle bir işe girişiyoruz şuan. :)
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: qeek - 24 Ekim 2019, 15:12:25
Hocam programı derledikten sonra bootloader kısmına uart ile alıp kendiniz yazsanız sonrada resetleyip programı yazdığınız yerden başlatsanız sorunu çözüyor mu?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: devrecii - 24 Ekim 2019, 16:49:29
Flasha sürekli kod yüklemek silmek cpu ömrünü kısaltır hele büyük programı parça parça yüklemek  ??? .

Ram de kod koşmak eğer kodların tamamını asm de yazıyorsanız çok mümkün kodu parça parça yükleyip çalıştırabilrisiniz, ama c++ da yazıyorsanız c++ kodlarının ne yapacağı mechul yanlış bir hafıza alanına veri yükleyebilir.

Tavsiyem emulasyon kod şöyle örnek vermek gerekirse msesela 

0xA5  0x4  0x8  0x5  /// bu kod 4 nolu integeri 8 nulu integerle topla 5 nolu inetgere ver
0xb8 0x5  //  5 nolu integeri uarta gönder
0xc9 0x5 0x10 // aşağıdaki  5 blok kodu 10h defa çalıştır 

gibi gibi  cpu bu kodları emulasyon oarak çalışrıracak ne reset ne kilit ne bişey istersen 1gb kod yaz.

Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 24 Ekim 2019, 19:35:26
Sorunu çözdüm test aşamasında çalıştırıp denedim.
@z hocamın dediği gibi tabloyu dolduruyordum fakat initleri disable etmeden çalışmadı. disableları da yapınca sorunsuz çalıştı.
kodu sadeleştirince, paylaşabildiğim kadarını buradan paylaşırım.

@iboibo hocam emülasyon kod nedir hiç bilmiyorum. fakat bu sürekli çalışan bir sistem değil sadece güncelleme geldiğinde çalışan bir sistem kodu parçalı yükleyip çalıştırma yok yani. Direkt program güncellemesi.
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 07 Kasım 2019, 16:47:33
@yldzelektronik hocam şu örnek ram'de koşuyor. ben de bunu baz alarak kendi kodumu modifiye ettim
int TestFunc(void)
{
  return(123);
}

#define FUNC_SIZE 64

typedef int (*pFunction)(void);

int RamFunc(void)
{
  uint8_t Buffer[FUNC_SIZE];
  pFunction RunFunc;

  memcpy(Buffer, (void *)((uint32_t)&TestFunc & ~1), FUNC_SIZE);

  RunFunc = (pFunction)&Buffer[1]; // +1 for Thumb code

  return(RunFunc());
}

memcpy'deki bit tersleme olayının sebebi mcu ramde tek adreslere thumb code atıp exceptionları denetliyor, çift adreslerdeyse programla ilgili verileri koşturuyormuş. ramde tek adrese kod taşıdığınızda çalışmıyor. bilginize.
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: PROTECH_ - 07 Kasım 2019, 18:04:38
2015'e bir firma icin atmelde kosan RF bootloader yapmistik.
IAR compiler ile. ATSAMD21 serisinin bootloader örneklerini incele derim. RAM de fonksiyon kosturma ile ilgili  faydali örnekler vardi.
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: OptimusPrime - 07 Kasım 2019, 18:16:02
@e-zeki
Calisiyor mu bu kod  :) Bi gariplik var gibi  :du:

- FUNC_SIZE in 64 oldugunu nereden biliyorsun?
- Ya Buffer ile TestFunc ayni alignment ozelligine sahip degilse?
- Ya Buffer icin ayrilan alani derleyici baska bir degisken veya degiskenler icin kullanirsa?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 13 Kasım 2019, 08:50:28
Alıntı yapılan: OptimusPrime - 07 Kasım 2019, 18:16:02@e-zeki
Calisiyor mu bu kod  :) Bi gariplik var gibi  :du:

- FUNC_SIZE in 64 oldugunu nereden biliyorsun?
- Ya Buffer ile TestFunc ayni alignment ozelligine sahip degilse?
- Ya Buffer icin ayrilan alani derleyici baska bir degisken veya degiskenler icin kullanirsa?
@OptimusPrime Hocam çok geç gördüm. korkunç hatalardan bahsediyorsunuz  :o
Keil için konuşuyorum:
- FUNC_SIZE belirlerken derleyicinin oluşturduğu htm uzantılı "Static Call Graph for image ...axf" dosyasından fonksiyonun (eğer herhangi bir yere dallanmıyorsa) boyutunu görebiliyorsunuz buna göre belirlenebiliyor.
- Alignment değişme ihtimalini hiç düşünmedim bile.  :du:
- Buffer local olduğu için stack'de tutuluyor. Scope'tan çıktığı an dediğinizin olma ihtimali yüksek (benim durumumda hiç olmadı) :-\  :'(

O zaman ben soruyorum:
- Buffer'ı new ya da malloc'la heap'e taşısam olası bir 3. durumun önüne geçmiş olur muyum?
- fonksiyon ve değişken adreslemelerinde aligment farklılığı olan bir durum örnek verebilir misiniz?
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: OptimusPrime - 13 Kasım 2019, 23:16:52
Derleyicinin sagi solu belli olmaz.  :D

Soyle bir arastirdim da keil de __ramfunc diye bir anahtar kelime yok sanki. Kullanma klavuzunda bu konu geciyormu bilemiyorum, bakmak lazim.

Yurutulen mantik dogru, eger fonksiyon icerisinde flasha dallanma yoksa bellekte bir yer ayrilarak fonksiyon ram e tasinabilir. Bu durumda fonksiyonun ne kadar yer kapladigini gormek icin derleyicinin urettigi dosyalardan faydalanilabilir. Sonrasinda fonksiyon isaretcisiyle ram da calisma saglanir. Fakat dedigim gibi 2 kritik nokta var. Ilki foksiyonun kullanilmayan bir bellek bolgesinde olmasi gerekiyor ki malloc veya linker bu isi cozebilir. Bu arada malloc un da alligned bir adres dondurmesi garanti degildir! Ikincisi ise, yine ayni yere geliyoruz ama, bu adresin allign olmasi gerekir (__attribute__ aligned vb)
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: yldzelektronik - 14 Kasım 2019, 14:38:07
Beyler sakin. Keil ve diğer bir çok geliştirme ortamı bunlar için hazır çözümler sunuyor.

Keil da aynı ram alanını hem değişkenlere hem de fonksiyona ayırmak için linker dosyasına bazı tanımlar yaparak bu işi çözebiliyorsunuz.

Daha kolay yolu da var. Koşturmak istediğiniz kodu tek bir dosyada toplayın, başka yerlere dallanmadığına (istenmeyen adreslere) emin olun, sonra o dosyaya proje ağacından sağ tıklayarak "Options For Target" seçin. Oradan istediğiniz adres tanımlarını yapın.

Sonra scatter dosyasına ramde koşacak dosyanın adıyla yeni alan tanıtın.

Hayırlı olsun. Artık o kodlar istediğiniz adreste. Şuanda bunları denemiş birisi olarak yazıyorum.

Normalde program qspi flash üzerinde çalışıyor. Güncelleme sırasında flasha yazma yapmam lazım. Bunun için Memory Mapped Enable modu kapamam gerekiyor. Bu durumda kodlar ramde çalışıyor. Yazma işi bitince yeniden açıyorum modu.

Sonra 16 MB flash içinde geziyorum. Dahili hafıza ile işim kalmıyor.
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: e-zeki - 14 Kasım 2019, 15:19:30
@yldzelektronik  hocam sizin
Alıntı yapılan: yldzelektronik - 14 Kasım 2019, 14:38:07"Options For Target" seçin. Oradan istediğiniz adres tanımlarını yapın.
dediğiniz şekilde yaptığımda derleyici kodun o bloğunu kod koşmaya başlamadan önce ram'e taşıyor. Yani ayda yılda bir kullanacağım bir kısım için ram hacmimi otomatikman düşürmüş oluyorum. fonksiyonu kullansamda kullanmasam da ramde yer kaplıyor. Benim öyle bir lüksüm olmadığı için bu şekilde yaptım.

@OptimusPrime __ramfunc bu keyword baya uzun zaman önce kaldırılmış sanırım hocam. Options For Target döneminden önce bu şekilde kullanılıyormuş büyük ihtimalle ama zaten yine dediğim gibi kodu ram'a başlangıçta taşımak için kullanılan bir yöntem bu. ben ihtiyacım varsa taşımak istediğim için bu yolu seçtim.
Başlık: Ynt: STM32 RAM'de kod koşturmak
Gönderen: OptimusPrime - 15 Kasım 2019, 10:16:40
@e-zeki
 ;) Mantikli. Yanliz bir alan ayirip malloc ile daha sonra free ile serbest birakilmasinda fayda var.

@yldzelektronik
Sakiniz zaten.  8-)