Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Cortex ARM => Konuyu başlatan: AsHeS - 25 Temmuz 2014, 10:28:46

Başlık: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 25 Temmuz 2014, 10:28:46
STM32F103VB kullanıyorum. GCC ile yaptığım debuglarda çağırılan fonksiyonun adresinin r7 registerine yazıldığını gördüm. Gelelim benim problemime diyelim ki init edilmemiş yanlış bir adrese ulaşmaya çalışanca, init edilmemiş periphe erişince vs.. hardfault_Handler a düşüyoruz. Yazılan kod buraya düştüğünde son çağırılan fonksiyonu öğrenme şansım var mıdır ?
r7 registerının içeriği fonksiyon içerisinde değiştirilebiliyor program tarafından koruma yok o tarafta GCC için anladığım kadarı ile.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: z - 25 Temmuz 2014, 10:38:07
Stackda geri donus adresin var.

Daha once denemedim ama hard fault rutininde

B        .

satirini

BX     LR

olarak degistirirsen zaten istedigin yere gitmen lazim. Debug icin deneyebilirsin.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: X-Fi - 25 Temmuz 2014, 15:49:14
Bu işlem için m3 içerisinde program counter(R15) zaten yapıyor __current_pc(); şeklinde çağırıyorsunuz.


Edit: Yeni farkettim sen debug için sormuşsun bu komut işini görmeyecektir çünkü kullanıldığı adres bilgisini dönüyor anladım.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: Burak B - 25 Temmuz 2014, 17:26:46
Aşağıdaki linki bir inceleyin.
HardFault Handler for Cortex-M (http://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/)
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 25 Temmuz 2014, 21:53:59
Alıntı yapılan: z - 25 Temmuz 2014, 10:38:07
Stackda geri donus adresin var.

Daha once denemedim ama hard fault rutininde

B        .

satirini

BX     LR

olarak degistirirsen zaten istedigin yere gitmen lazim. Debug icin deneyebilirsin.
Alıntı yapılan: X-Fi - 25 Temmuz 2014, 15:49:14
Bu işlem için m3 içerisinde program counter(R15) zaten yapıyor __current_pc(); şeklinde çağırıyorsunuz.


Edit: Yeni farkettim sen debug için sormuşsun bu komut işini görmeyecektir çünkü kullanıldığı adres bilgisini dönüyor anladım.
Alıntı yapılan: ByteMaster - 25 Temmuz 2014, 17:26:46
Aşağıdaki linki bir inceleyin.
HardFault Handler for Cortex-M (http://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/)

Hata ve onun sebepleri hakkında bilgilendirilebiliyoruz(yanlış adres erişimi vs..). Fakat benim aradığım şu hardfaulta düşüldüğünde en son içinde bulunduğum ya da girdiğim fonksiyonun entry pointini alabilmek dokümanlardan ve sizlerden anladığım kadarı ile pek mümkün değil. 
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: X-Fi - 25 Temmuz 2014, 22:02:34
Bir yöntem var aklıma gelen anlatayım istersen deneyebilirsin...

__current_pc() fonksiyonunu Bir timer ile kurup DMA ile RAM adrese yüklersen hartfault a düştüğünde timer ı durdurup son değeri RAMden okuyarak RT scheduler'ı bozulmadan hata geri dönüşü alınabilir.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 25 Temmuz 2014, 22:24:04
Alıntı yapılan: X-Fi - 25 Temmuz 2014, 22:02:34
Bir yöntem var aklıma gelen anlatayım istersen deneyebilirsin...

__current_pc() fonksiyonunu Bir timer ile kurup DMA ile RAM adrese yüklersen hartfault a düştüğünde timer ı durdurup son değeri RAMden okuyarak RT scheduler'ı bozulmadan hata geri dönüşü alınabilir.
Hocam PC çalışma esnasında durmadan değişmesi muhtemel birşey yapı programın ortasında adresi verirse belki bir şekilde fonksiyon büyüklüğü ve başlangıç adresleri ile yakalanbilir ama bunu yakalayabilmek için timer ın ns düzeyinde çalışıp komut atlamaması gerekiyor. us seviyesindekiler ile 72MHz de koşan yapı da atlamalar yaşanabilir diye düşünüyorum. Ben daha çok M3'ün registerlerınden ümitli idim fakat olmadı başka yöntemlere yöneleceğim.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: z - 25 Temmuz 2014, 22:31:42
Bahsettigim yontemde hard faultun olup sistemin eventin urettildigi noktayi tespit edersin. Soz konusu hataya neden olan satirin ait oldugu fonksiyonun baslangic adresini bulmak biraz yaş iş.

Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 25 Temmuz 2014, 23:49:01
Alıntı yapılan: z - 25 Temmuz 2014, 22:31:42
Bahsettigim yontemde hard faultun olup sistemin eventin urettildigi noktayi tespit edersin. Soz konusu hataya neden olan satirin ait oldugu fonksiyonun baslangic adresini bulmak biraz yaş iş.


Hocam LR registerı tam olarak nasıl kullanılıyor. Bir önceki dallanmayı falan mı tutuyor ?
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: z - 26 Temmuz 2014, 00:38:59
Alıntı yapılan: AsHeS - 25 Temmuz 2014, 23:49:01
Hocam LR registerı tam olarak nasıl kullanılıyor. Bir önceki dallanmayı falan mı tutuyor ?

LR normal rutinlerde geri donus adresini saklar. Ancak int rutinine girdiginde LR geri donus adresini degil EXC_RETURN denilen degeri tutar. O yuzden LR degeri int rutininde isine yaramaz.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 26 Temmuz 2014, 00:41:57
Alıntı yapılan: z - 26 Temmuz 2014, 00:38:59
LR normal rutinlerde geri donus adresini saklar. Ancak int rutinine girdiginde LR geri donus adresini değil EXC_RETURN denilen degeri tutar. O yuzden LR degeri int rutininde isine yaramaz.
Hard Fault'a düştükten sonra düştüğümüz yerin adresini buraya kayıtlar diyorsunuz yani.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: z - 26 Temmuz 2014, 00:48:57
Hayir.

Harfaulta exception olustugunda R0,R1,R2,R3, R12, LR ve PSR degerleri stacka atilir. Bu asamada LR degerine EXC_RETURN degeri yuklenir. Dolayisi ile geri donus adresi LR de degildir.

Ancak;

@Gerbay

MSP degerini okuyup stacktaki degerlere ulasmanin garantisi yok. Zira exception olustugunda MSP nin kullanildiginin garantisi yok. PSP de kullaniliyor olabilir.

MSP den mi yoksa PSP den mi okuyacagini bilmen gerekir.

Cok emin konusmuyorum ama boyleydi.


mesaj birleştirme:: 26 Temmuz 2014, 00:51:47

Evet MSP mi PSP mi ogrenmen gerekiyor. Bunun icin Control Regi okumak gerekiyor. Ardindan hangi stack kullaniliyorsa o stackdan stacka atilmis regleri tek tek cekersin.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: z - 26 Temmuz 2014, 01:08:10
LR ye bakmak bence tehlikeli.

Neden dersen;

ARM da int rutinleri ve fonksiyon rutinleri diye bir ayrim yok.

Eger bakilacaksa da 31. bite bakip rutini fonksiyon olarak cagirmadigimizdan emin olmak lazim.

Aksi takdirde buga acik bir kod olur.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 26 Temmuz 2014, 01:12:59
Alıntı yapılan: gerbay - 26 Temmuz 2014, 00:32:56
hocam fault olduğunda işlemci hardfault handler a dallanmadan önce main stack için ayrılan bölgeye register ları atıyor. siz hardfault handler a girince main stack pointer ın değerini okuyun, şu şekilde;


MRS   r0, MSP


şimdi burada r0 ı 32-bit lik elemanlardan oluşan diziye pointer olarak düşünün,

R0 + 0 da hardfault dan önceki R0 var, benzer şekilde
R0 + 4 de R1,
R0 + 8 de R2,
R0 + 12 de R3,
R0 + 16 da R12,
R0 + 20 de LR,
R0 + 24 de PC,
R0 + 28 de xPSR değerleri var.

Düşmeden hemen önce ki PC yi kayıt altına alabiliyorsak .map dosyası ile ilgili fonku bulabiliriz demektir bence.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: z - 26 Temmuz 2014, 01:15:31
Ama sen ilgili fonksiyonun giris noktasini ariyorsun.

Yani

void func()
{
.....
.....
.....
---> exception noktasi
----
----
}

Exception noktasini yakalayabilirsin. Ama func adresini tespit etmek cok zor.



mesaj birleştirme:: 26 Temmuz 2014, 01:16:44

Ama debug rutininden ben zaten bu satirin hangi fonksiyon icinde oldugunu biliyorum kendim anlarim dersen olur tabiki.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 26 Temmuz 2014, 01:22:34
Alıntı yapılan: z - 26 Temmuz 2014, 01:15:31
Ama sen ilgili fonksiyonun giris noktasini ariyorsun.

Yani

void func()
{
.....
.....
.....
---> exception noktasi
----
----
}

Exception noktasini yakalayabilirsin. Ama func adresini tespit etmek cok zor.



mesaj birleştirme:: 26 Temmuz 2014, 01:16:44

Ama debug rutininden ben zaten bu satirin hangi fonksiyon icinde oldugunu biliyorum kendim anlarim dersen olur tabiki.
.map dosyasının dizilimini incelediğimizde ardı ardına dizilmiş fonksiyonların alanlarını görebiliyoruz. Örneğin ;
.text.LCD_DisplayChar
                0x08001f64       0x44 ..\obj\driver.o
                0x08001f64                LCD_DisplayChar
.text.LCD_DisplayString
                0x08001fa8       0x60 ..\obj\driver.o
                0x08001fa8                LCD_DisplayString

Eğer exception noktası 0x08001f75 ise LCD_DisplayChar fonksiyonunun içerisidir diye yorumlanabilir. Amacım debugger kullanmadan bu işleri hallettmek.


void HardFault_Handler()
{
     asm("TST    LR, #4");//
     asm("ITE EQ");
     asm("MRSEQ R0, MSP");
     asm("MRSNE R0, PSP");
     asm("B __cpp(mon_dump_stack)");


}

mon_dump_stack(uint32_t stack[])
{
....//Okuma işlemleri
};


Bu şekilde alınabilir gibi duruyor ?
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: AsHeS - 26 Temmuz 2014, 01:50:34
Alıntı yapılan: gerbay - 26 Temmuz 2014, 01:45:24
aynen öyle hocam, stack[6]  da tam olarak olaya sebep olan instruction larin adresi var..
.map dosyasını da inceledik mi ilgili adresi iki fonksiyon adresi arasına kıstırırız böylelikle düştüğümüz yeri bulabiliriz denemelere geçeyim hemen.

mesaj birleştirme:: 26 Temmuz 2014, 01:58:11

GCC (CooCox IDE) ile kod düşülen yerin adresini alan kod aşağıda ki şekilde

void mon_dump_stack(unsigned long int stack[])
{
unsigned long int fault_pc_addr;

fault_pc_addr = stack[6];
return;
}
void   HardFault_Handler(void){
    asm("TST    LR, #4");//
    asm("ITE EQ");
    asm("MRSEQ R0, MSP");
    asm("MRSNE R0, PSP");
    asm("BL mon_dump_stack");
while(1)
{};
}


mon_dump_stack te zorla UART donanımına birşeyler söylettirerek adresi alır ve .map dosyası ile inceleyebilirim.

@z , @gerbay ve @X-Fi hocam yardımlarınız için teşekkür ederim.
Başlık: Ynt: Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?
Gönderen: X-Fi - 26 Temmuz 2014, 12:00:03
Ds5 professional ve realview mdk için aşağıdaki şekilde düzenlemek gerekti denedim çalışıyor.

unsigned long PC_Fault;

void HardFault_Handler_C(unsigned long * HardFault_Args)
{
    PC_Fault=HardFault_Args[6];
    while(1)
    {
    }
}

__asm void HardFault_Handler(void)
{
TST LR, #4
ITE EQ
MRSEQ R0, MSP
MRSNE R0, PSP
B __cpp(HardFault_Handler_C)
}


Birde .map dosyasında girilen adresi bulan ve fonksiyon ismini yazdıran bir C# penceresi yapan olurda paylaşırsa seviniriz.

Herkeze iyi çalışmalar.