STM32 RAM'de kod koşturmak

Başlatan e-zeki, 23 Ekim 2019, 17:25:27

e-zeki

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?

OptimusPrime

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?
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

z

0. sektoru siliyormusun?

Siliyorsan vektorleri rama yada silmedigin flash sektorlerine tasiyormusun?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

e-zeki

@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. 

yldzelektronik

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?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

e-zeki

@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.

z

#6
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.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

OptimusPrime

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.
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

e-zeki

@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?

e-zeki

@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. :)

qeek

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?

devrecii

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.


e-zeki

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.

e-zeki

@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.

PROTECH_

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.
Multi-Core ,RTX,ThreadX, FreeRTOS, MODBUS  RTOS - Electronic-Hardware -- BERLIN