STM32F407 Cortex M4 şamataları

Başlatan bunalmis, 16 Ekim 2011, 17:14:50

LukeSkywalker

Cevabınız icin tesekkurler. Peki hocam mazur görün ilk iki biti neden sifirliyoruz?

Klein

Bu örnekte adr parametresine belirli bir değerin üstünün yanlışlıkla atılmasını engellemek için kullanılmış.
Programcı  adres değeri için 0xFF bile verse  adres verisi olarak hiç bir zaman 0x3F en daha büyük bir sayı gönderilmez.
Örnekteki yazma ve okuma rutinlerine dikkat edersen,  yazma rutininde adresin son bitinin 1 yapıldığını görürsün.  Ama okuma bitinde bu yok. Eğer programcı okuma yapmak isterken yanlışlıkla son biti 1 yaparsa  karşı taraf bunu yazma isteği olarak algılayabilir. Bu da istemeyeceğimiz sonuçlar doğurabilir.

Programcı yanlışlık yaparsa zaten  programın çalışmasından bu yanlışı anlayabilir , ne gerek var diyebilirsin.
Bu örnek için belki söylenebilir. Ama sorun her zaman programcıda olmayabilir.  Çok daha karmaşık işlemlerde değer başka bir operasyon esnasında değişebilir.



z

Ağzı yanan yoğurdu üfleyerek yermiş.

Kodlara yapılacak bu tip küçük eklentiler, kafanızın çok karışık ve yorgun olduğunuz dönemlerde yapacağınız hatalardan sizi korur.

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

LukeSkywalker

Hocam cevaplarinz için teşekkür ederim. Tecrübelerinizi ve bilginizi paylaşmanız gerçekten asilce.
Klein hocam okuma esnasında 1 yapılıyor 7. bit değil mi?

Klein

evet okuma isteği gönderilirken.

cooldoubtless

özür dilerim daha yeniyim..umarım bu sorumla canınızı sıkmam ama

while(!(RCC->CR & 0X00020000));

satırında RCC_CR nin içeriğini 00020000 ile AND işlemine sokuyoruz haliyle diğer bitler sıfırlanıyor ve bizi ilgilendiren 17.bit eğer 1 ise sonuç RCC_CR içeriği 00020000 oluyor..değilse 00000000 oluyor sonra birde bunun değilini alıyoruz..while yapısının içi ya FFFFFFFF ya da FFFFDFFF oluyor..içeride bir eşittir ifadesi de sorgulanmıyor..ben bu satırdan hiç bir şey anlayamadım lütfen birisi yardım etsin..ayrıca konu başında -> sembolünü sanki atama sembolüymüş gibi kabul ettik sonra açıklamasını yaparız diye geçtik ama başka yerde bulamadım açıklamasını yapıldı da ben mi göremedim yoksa açıklaması yapılmadı mı?

cooldoubtless

Çok teşekkür ederim gerbay hocam açık bir anlatım olmuş..

cooldoubtless

SAYGI DEĞER ARKADAŞLARIM BEN BU DISCOVERY KİTTE BUNALMIŞ HOCAMIZIN YAZDIĞI HİÇ BİR PROGRAMI ÇALIŞTIRAMADIM...YÜKLEME BAŞARIYLA GERÇEKLEŞTİRİLİYOR..PROGRAMLARI ATMAKTA SIKINTI YOK ANCAK USER BUTONUNA DA BASSAM RESET TUŞUNA DA BASSAM HİÇ BİR ŞEY OLMUYOR..DEBUG ETSEM YİNE AYNI..DEĞİŞEN BİŞEY YOK..KENDİ ÖRNEK BLINKY PROGRAMINI ATINCA GAYET GÜZEL ÇALIŞIYOR..BEN NEREDE HATA YAPIYORUM?

fatih6761

Sorun büyük ihtimalle main sembolü hatasıdır.İlk başta bulması zor oluyor ama debug ederken rastladım.
startup_stm32f4xx.S dosyasında;
; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

yazan kısmı
; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  main                           ; Burası

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =main             ; ve burası degisecek
                 BX      R0
                 ENDP

Şeklinde değiştirin.Keilda debug ettiğinizde hard faulta atmaması gerekir.Eğer hatanız Hard Fault ise tabi.

fatih6761

#969
@gerbay hocam söylediklerinize katılmıyorum buradaki __main derleyici sembolü.İşletim sistemleriyle uğraştığımdan biliyorum her derleyici sembolleri farklı yorumluyor (siz de biliyorsunuzdur). Debug modunda incelerseniz __main sembolü çağrıldığında çekirdek HardFault moduna düşüyor.Ayrıca yukarıda verdiğim ilk örnekteki orjinal durum ST FW 1.1.0 kütüphanesindeki dosyada yer alıyor.Keil yükleme klasörü > ARM > Startup > ST > STM32F4xx klasörü içerisindeki startup_stm32f4xx.s dosyası da IMPORT main koduyla doğru sembolün __main değil main olduğunu kanıtlıyor(Satır 173).Aslında bu durum genellikle GNU derleyicilerinde oluyor.GCC ve G++ derleyicileri ( GNU başlığı altında ) sembolleri Object koduna __sembol_adi şeklinde Export ediyor.Keil'ın kendi derleyicisi ise (RealView oluyor) sembolleri sembol_adi şeklinde export ediyor.
inceledim + denedim ^ test ettim ~= çalışıyor :)

cooldoubtless

Sadece keil de değil IAR da da bunalmış hocamızın yazdığı kodları aynen çipe yükledim ama yine çalışmadı..en basit yanıp sönen buton uygulaması bile..ama kendi örnek uygulamaları çalışıyor..bu programları aynen alıp derleyip çalıştırabilen var mı yoksa kimse denemedi mi? :)

cooldoubtless

özür dilerim arkadaşlar konuya tam hakim olmadığım için şuanda başka birşeyden mi bahsediyorsunuz yoksa programların çalışmaması sorunundan mı anlayamadım? :) gerbay hocamın sölediği fpu seçeneğini not used yaparak yükledim programı yine çalışmadı..bir ledi yakmak ne kadar zor bu arm de? hayır hata söylediğiniz gibi sistemden kaynaklanan bir şeyse benden başka kimse denemedi mi bu programları 7 8 aydır bu kitte anlamadım ki? :)

rclk

Arkadaşlar bülent hocanın ilk uygulaması olan led yakma uygulmasını derliyorum sorun yok ,fakat kite attığımda hiçbir action olmuyor çakıldım kaldım nerde hata yapıyorum
#include "STM32F4xx.h"
 
void SystemInit()
{
    RCC->AHB1ENR|=0x00000008;    // GPIOD donanımının clock sinyalini uygulayalım
    GPIOD->MODER=0x55000000;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
    GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
} 
 
int main()
{
    while(1)
   {
     GPIOD->ODR= 0x0000F000;     // Ledler yansin
     GPIOD->ODR= 0x00000000;     // Ledler sonsun
   } 
}
Herşeyi salla ama ÇAYI demle hacı..

fatih6761

@gerbay hocam haklısınız, afedersiniz  :-[ .Kodları disassembly penceresinde teker teker inceledim.Dediğiniz gibi derlenmiş çıktı dosyası yürütülürken ilk işletilen kod __main kodu oluyor.Bu kod bellekte 0x08000188 adresinde.Bizim main fonksiyonumuz ise daha ileride.__main den sonra zero init, scatter load şeklinde data segment belleğe kopyalanıyor.Sorduğunuz sorunun cevabı da açık zaten.
Aslında yanılgımın sebebi GCC derleyicisi.Farklı derleyiciler arasında uyumsuzluk yaşamamak için symbol prefixleri kullanıyorum.Yani eğer __GNUC__ tanımlıysa sembollere '_' ekle, değilse ek yok gibi.Bu da alışkanlık yapıyor  _ öneklerini hep sembol olarak algılıyorum :)
Birde sorum olacak, bildiğiniz gibi elimizdeki mcu da kodlar çalışmadan önce Ram adreslerine remap ediliyor.Yani yansıtılıyor.Bu kodlar yalnız okunabilir mi? Yoksa veri akışı çift yönlü mü? Bu yolla Bellek alanına doğrudan erişim sağlayabilir miyiz? Yada bunun için section initializer mantığında bir kod yazarak dinamik veri akışı sağlayabilir miyiz?

serhat1990

Alıntı yapılan: rclk - 08 Ağustos 2012, 02:42:11
Arkadaşlar bülent hocanın ilk uygulaması olan led yakma uygulmasını derliyorum sorun yok ,fakat kite attığımda hiçbir action olmuyor çakıldım kaldım nerde hata yapıyorum
#include "STM32F4xx.h"
 
void SystemInit()
{
    RCC->AHB1ENR|=0x00000008;    // GPIOD donanımının clock sinyalini uygulayalım
    GPIOD->MODER=0x55000000;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
    GPIOD->OSPEEDR= 0xFFFFFFFF; // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
} 
 
int main()
{
    while(1)
   {
     GPIOD->ODR= 0x0000F000;     // Ledler yansin
     GPIOD->ODR= 0x00000000;     // Ledler sonsun
   } 
}


Bu programı keilde debug ederek çalıştırabilirsin. Yani debug'ı açıp f11 ' e basarak adım adım programı işletirsin.
Altında bir tane daha örnek var onu atarsan debug etmeden program çalışır. Programı atınca.