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
Byte say;
Tanimini kullanmak istediğin fonksiyonun üzerinde
Yapman gerekiyor...
Xc boyle temel bir bug barindirmaz saniyorum.
Üstünde tanımlı zaten. Taa programın başında bir yerlerde. Diğer türlü zaten derleme başarısız olur.
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.
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.
İ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ı?
BYTE diye tür var. Yeni çıkmış galiba. unsigned char ile aynı oluyor.
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.
değişkene 0 dan farklı değer verip denermisiniz ?
byte sayi=1 gibi
birde sadece byte veri demi yapıyor bunu
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();
}
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.
Benim hata dediğim durum gercek değil galiba. Baska sorunlar nedeniyle kodu komple degistirdim. Sade bir ornek ile henuz deneme yapamadim.
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 :)
olur mu böyle şeyya? yakışyor mu xc8 gerçekten böyle yapar mı?
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..
@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
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.
doğrudan değiştirmek dururken neden ?
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.
ben aşağıdaki gibi yapıyorum
unsigned char sayi;
main
{
}
fonksiyon
{
extern unsigned char sayi;
}
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ış.
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?
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.
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ş
Doğrudur.Zaten gelişmiş işlemcilerde stack ve heap boyutunu kendimiz belirleyebiliyoruz.
Teşekkür ederim
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)