Picproje Elektronik Sitesi

DERLEYİCİLER => Microchip XC Serisi => Microchip XC8 => Konuyu başlatan: t2 - 02 Ocak 2014, 22:00:00

Başlık: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: t2 - 02 Ocak 2014, 22:00:00
BYTE say;
şeklinde tanımlı global (zannettiğimiz) değişkenimiz olsun.

Main içinde çeşitli satırlarda:

fonksiyon1(); say++;

şeklinde kullanılıyor normal çalışıyordu.  Bunun yerine say++; kısmını fonksiyon1 içine  ekleyeyim dedim. Fakat o zaman program istediğim gibi çalışmıyor resmen sapıtıyor. başka değişiklilk yapmadan sadece bu kısmı değiştirdim. Eski haline gelince normal çalışıyor. yani ana döngü içinde global değişkeni değiştirmeliymişiz.


Acaba bu durum  temel bilgi eksikliğimden mi kaynaklanıyor? Global değişkenin fonksiyonlar içinden de değiştirilebilmesi için ek bazı  ifadeler mi var?  Yoksa xc8 sürümüne ait sorun mu? v1.21 kullanıyorum
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Erol YILMAZ - 02 Ocak 2014, 22:12:28
Byte say;
Tanimini kullanmak istediğin fonksiyonun üzerinde
Yapman gerekiyor...

Xc boyle temel bir bug barindirmaz saniyorum.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: t2 - 02 Ocak 2014, 22:15:32
Üstünde tanımlı zaten. Taa programın başında bir yerlerde. Diğer türlü zaten derleme başarısız olur.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Tagli - 02 Ocak 2014, 22:38:37
fonksiyon kesme içinden de çağrılıyor mu veya say'a kesme içinde de erişiliyor mu?
fonksiyon içinde başka bir say tanımlanmış olabilir mi? (maskeleme meselesi)
say++ yazılmış olduğu gibi tek başına mı kullanılıyor yoksa daha uzun bir işlemin bir parçası mı?
BYTE olarak tanımlanan tür gerçekte nedir (bildiğim kadarıyla XC8'de doğrudan byte adında bir değişken türü yok.)
Programın sapıtması biraz bulanık bir ifade olmuş. Mümkünse gerçek sistemde, değilse simulasyon ortamında debug yapılmasını tavsiye ederim. say değişkenine ne olduğunun anlaşılması gerek öncelikle. Mesela 14, sonra 15, sonra 16 olup sonra birden 243 falan oluyor mu?

gerbay hocam, anladığım kadarıyla değişken zaten dışarıda tanımlanmış. Sadece erişilen yer değişiyor.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: t2 - 03 Ocak 2014, 09:44:58
Kesme yok. Değişken tüm fonksiyonların dışında tanımlanınca static yazmaya gerek olmaz sanıyorum.

Programda başka mantık hatası da olabilir. Sorun devam ederse bunu gösterebilmek için ayrı bir kod iletirim. Belki de bu kodu hazırlarken sorunu fark edebilirim.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Gökhan BEKEN - 03 Ocak 2014, 11:35:50
İlk dikkatimi çeken, xc8 de BYTE gibi bir tür yok.
Değişkene ilk değer ataması olarak 0 vermenizi tavsiye ederim, sırf bu yüzden bile olabilir.
say değişkeni fonksiyondan sonra tanımlanmışsa belki ondan olmuyordur.
Derlediği halde mi çalışmıyor, yoksa hiç mi derlemiyor?
Muhtemelen gözden kaçırdığınız birşey var, debug yaptınız mı?
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: t2 - 03 Ocak 2014, 11:50:10
BYTE diye tür var. Yeni çıkmış galiba. unsigned char ile aynı oluyor.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Gökhan BEKEN - 03 Ocak 2014, 11:52:51
Hocam o kadar tavsiyede bulundum, bir de ben deneyim dedim, sizin sorun bende de oldu. Debug yapınca farkettim ki, main fonksiyonu içinden global değişkene değer verdiğimde 0 oluyor.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: muhittin_kaplan - 03 Ocak 2014, 12:00:18
değişkene 0 dan farklı değer verip denermisiniz ?
byte sayi=1 gibi
birde sadece byte veri demi yapıyor bunu
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Gökhan BEKEN - 03 Ocak 2014, 12:01:11
Sorunda şu imiş:
ben deneme yaparken "a" isminde bir değişken kullandım
aslında ben daha önce main içinde daha sonra başka bir şey için unsigned char a; olarak kullanmışım. Deneme yaparken de unutmuşum daha önce böyle birşey yaptığımı.
Sizde de böyle bir sorun olabilir.

Böyle yapınca sorun yok:
int asda=0;
void deneme(void){
    asda=5;
}
void main(void)
{
    deneme();
}
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: muhittin_kaplan - 03 Ocak 2014, 15:29:28
eğer hem global de hemde fonksiyonun içerisinde tanımlarsanız local değişken olmaz mı hata bu muymuş sanki t2 farklı diyor.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: t2 - 03 Ocak 2014, 15:52:27
Benim hata dediğim durum gercek değil galiba. Baska sorunlar nedeniyle kodu komple degistirdim. Sade bir ornek ile henuz deneme yapamadim.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: elektronart - 03 Ocak 2014, 15:58:25
Kodunuzun biraz daha büyük olduğunu ve örnek olsun diye bu şekilde kısa bir kod yazdığınızı varsayıyorum.
Değişkenler yaratılırken RAM içinde adres 0dan başlayarak önce global değişkenler yaratılır. Sonrasında global değişkenlerin bittiği yerden HEAP adı verilen bölge başlar alloc, malloc gibi komutlarla yaratılan değişkenler yer alır. Geri kalan bölgenin son adresinden başlayarak ramin 0 adresine doğru da STACK kullanılır. Programın herhangi bir yerinde stack geri kalan alanı doldurursa global değişkenlere sıçrar ve bu değişkenlerinizi bozabilir. Global değişkenleri azaltabilir veya bu değişkenin sırasını değiştirebilirsiniz. Şanslıysanız bu değişken kurtulur, şanssızsanız başka bir değişken bozulur :)
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: t2 - 03 Ocak 2014, 16:04:46
olur mu böyle şeyya? yakışyor mu xc8 gerçekten böyle yapar mı?
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: atioky_216 - 03 Ocak 2014, 17:39:05
 Temel c den hatirladigim kadari ile static degiskenleri alt fn ile degistirmenin en guzel yolu o degisken adresini bir pointere atayip adres cagirarak degisiklikleri yapmak diye hatirliyorum..
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Ateş Erim - 03 Ocak 2014, 17:40:05
@elektronart,
http://www.circuitstoday.com/pic-16f877-architecture-and-memory-organization (http://www.circuitstoday.com/pic-16f877-architecture-and-memory-organization) linkindeki dökümanın "program memory" kısmında şöyle bir şey diyor:

The PIC16F87XA family has an 8-level deep x 13-bit wide hardware stack. The stack space is not a part of either program or data space and the stack pointers are not readable or writable. In the PIC microcontrollers, this is a special block of RAM memory used only for this purpose.

Baştan söyliyeyim, ben çok çaylağım daha. Ama burada yazanı ben şöyle yorumluyorum: ne stack alanına, stack yazmaçlarından başka kimse bişey yazabilir; ne de stack yazmaçları kendi alanlarından başka bir yere tecavüz edebilir.  Stack yazmaçları kendi alanlarında mutlu mesut yaşarlar. Sığamadılar mı da (16F87X için misal 9. Seviye stack çağrılmaya kalkışıldığında) stack overflow hatası oluşur.
Yanılıyor muyum? Yanılıyorsam neyi atlıyorum ?

Kolay gelsin
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: elektronart - 03 Ocak 2014, 17:48:24
sadece xc8 yapsa iyi, işletim sistemi olmadığı sürece tüm mikroişlemciler yapar bunu. Bunu için kodun ne kadar stack kullandığını analiz eden uygulamalar var, küçük bir ihtimalle kullandığın geliştirme ortamı içinde böyle bir araç olabilir.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: muhittin_kaplan - 03 Ocak 2014, 17:56:44
doğrudan değiştirmek dururken neden ?
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Tagli - 03 Ocak 2014, 19:09:00
Ortalık epey karışmış...

elektronart, XC8'de zaten dinamik alan ayırma diye birşey yok. Ayrıca, bildğim kadarıyla recursion da desteklenmiyor. Bu durumda stack alanının gidip de bir başka değişken alanını basması söz konusu olamaz. Dinamik alan ayırma olmadığından, yazılımsal stack derleme anında kesin olarak belli oluyor. Bir sorun olsaydı derleme anında hata vermeliydi. XC16'da işler nasıl bilmiyorum çünkü onda dinamik hafıza olayı vardı. Ama yine de, bildiğim kadarıyla heap'in sınırları da zaten derleme anında çiziliyor. Stack'ın bu bölgeye derleme sırasında girmesine derleyici izin vermez bence.

ta2cye, o stack bu stack değil :) .  Doğrudur, fonksiyon geri dönüş adreslerini saklayan donanımsal stack'a erişim mümkün değil (PIC18'de bir miktar maymunluk ile yapılabiliyor bu). Ama bizim bahsettiğimiz stack, derleyicinin fonksiyon yerel değişkenleri ve diğer işlemler için oluşturduğu yazılımsal stack. Bu arada, 8 bitlik PIC mimarileri için konuşuyoruz. 16 bitliklerde olay farklı.

Dediğim gibi, kodu satır satır işletip değişkenin nerede saçmaladığını bulmak lazım. Yoksa yorum yapmak mümkün değil. t2, hatalı çalışan bir örnek kod verebilirsen kurcalayalım.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: korcenk - 03 Ocak 2014, 20:53:14
ben aşağıdaki gibi yapıyorum

unsigned char sayi;
main
{
}

fonksiyon
{
extern unsigned char sayi;
}

Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Tagli - 03 Ocak 2014, 21:04:27
extern'in header dosyaları dışında kullanıldığını görmemiştim. Ama bence işi karıştırmaya gerek yok. Fonksiyon içinden global değişkene zaten doğrudan erişilebilir. Senin yazım biraz Python'u andırmış.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Ateş Erim - 03 Ocak 2014, 23:21:50
Alıntı yapılan: Tagli - 03 Ocak 2014, 19:09:00

ta2cye, o stack bu stack değil :) .  Doğrudur, fonksiyon geri dönüş adreslerini saklayan donanımsal stack'a erişim mümkün değil (PIC18'de bir miktar maymunluk ile yapılabiliyor bu). Ama bizim bahsettiğimiz stack, derleyicinin fonksiyon yerel değişkenleri ve diğer işlemler için oluşturduğu yazılımsal stack. Bu arada, 8 bitlik PIC mimarileri için konuşuyoruz. 16 bitliklerde olay farklı.


Hımm açıklama için teşekkür ederim. Soft stack diye birşey duymuştum (henüz ne olduğunu bilmiyorum. İlk fırsatta araştıracağım) Bu bahsettiğiniz stack, sanırım soft stack. Doğru mudur?
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Tagli - 04 Ocak 2014, 09:09:58
Evet öyle. İşlemci mimarisi tarafından doğrudan desteklenmiyor, yani stack'lara has push ve pop komutları donanımsal olarak yok. Tamamen derleyici tarafından oluşturuluyor. Yani asm'de kod yazarken mesela böyle birşey oluşmaz (sen özellikle tasarlayıp eklemediğin sürece). Bu arada, özellikle PIC18'lerde, derleyicinin kendi stack'i üzerinde daha rahat çalışabilmesi için FSR register'ları 16 serisindekilere göre biraz geliştirilmiş. Derleyici dokümantasyonuna bakarsan, bu register'ların (pointer gibi çalışırlar zaten) yazılım stack'i ile ilgili özel görevleri olduğunu görebilirsin.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Ateş Erim - 04 Ocak 2014, 09:25:34
Ya kolaycılık yaptığımın farkındayım ama, araştırmadan önce son bir soru sormak istiyorum. Aceleciliğimi mazur görün lütfen.
Asm haricinde bir derleyiciyle program yazarken, "işlemcinin desteklediği stack sınırına dikkat edersem, derleyici ayrıca soft stack yapmaz" önermesi doğru mudur? Yoksa bu da derleyiciden derleyiciye değişen bir durummudur ?
Teşekkürler/iyi çalışmalar
Ateş
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: yamak - 04 Ocak 2014, 12:41:23
Doğrudur.Zaten gelişmiş işlemcilerde stack ve heap boyutunu kendimiz belirleyebiliyoruz.
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: Ateş Erim - 04 Ocak 2014, 17:04:47
Teşekkür ederim
Başlık: Ynt: Fonksiyon içinden global değişkeni değiştirme sorunu
Gönderen: elektronart - 05 Ocak 2014, 15:46:23
XC8lerle ilgili yorumum için özür diliyorum. Aşağıdaki dokümana göre söylemiştim. XC8lerde heap olmaması durumu değiştiriyor tabi. (Bilgilendirme için teşekkürler Tagli)
http://www.iar.com/Global/Resources/Developers_Toolbox/Building_and_debugging/Mastering_stack_and_heap_for_system_reliability.pdf (http://www.iar.com/Global/Resources/Developers_Toolbox/Building_and_debugging/Mastering_stack_and_heap_for_system_reliability.pdf)