Cortex M3 te çağrılan fonksiyonun adresi alınabilir mi ?

Başlatan AsHeS, 25 Temmuz 2014, 10:28:46

AsHeS

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.

z

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.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

X-Fi

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.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

Burak B

"... a healthy dose of paranoia leads to better systems." Jack Ganssle

AsHeS

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

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. 

X-Fi

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.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

AsHeS

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.

z

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

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

AsHeS

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 ?

z

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.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

AsHeS

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.

z

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.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

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.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

AsHeS

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.

z

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.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com