Hafızanın bir bölümünü uarttan Yollamak

Başlatan muhittin_kaplan, 23 Ağustos 2015, 20:06:48

muhittin_kaplan

Kısaca Struct yada Array yollayacağım Usarttan, bunun için bu yapı/dizi nin başlangıç adresini öğrenip bytebyte yollamam gerek.
Bu işi için dün ve bugün uğraşmk için kendime zaman ayırmıştım, bün biraz uğraştım ama nedense veriler yanlış geliyor.

typedef struct    __attribute__((__packed__)) UsartStructVeri { //hafýza yerleþiminde arada boþluk kalmasýn deðil mi
    int8_t int8Deger;//1 byte
    int8_t int8Deger2;
    int16_t int16Deger;//2 byte
   int32_t int32Deger;//4 byte
   int64_t int64Deger;//8 byte

} UsartStructVeri;


void sendUsart(struct UsartStructVeri value) {
    uint8_t *baslangic = (uint8_t*) (&value);
    int8_t sizeValue=sizeof(value);
    int8_t loop;

    for(loop=0;loop<sizeValue;loop++)
        //while( !(USART1->SR & 0x00000040) );
        USART_SendData(USART1, *baslangic++);

    }


int main(void) {
    LEDInitialize();
    GPIOInitialize();
    UART_Initialize();
    NVICInitialize();

    //USART_puts("a");
    GPIO_SetBits(GPIOD,GPIO_Pin_13);
    UsartStructVeri MyUsartStructVeri;

    MyUsartStructVeri.int8Deger=65;
    MyUsartStructVeri.int8Deger2=66;
    MyUsartStructVeri.int16Deger=0xAAAA;
    MyUsartStructVeri.int32Deger=0xAAAAAAAA;
    MyUsartStructVeri.int64Deger=0xAAAAAAAAAAAAAAAA;

    sendUsart(MyUsartStructVeri);
    while (1) {}
}

Icarus

Bu C++ olmuş ondan. Derleyici C99 ayarına getirirseniz direkt derleme hatası verir.
typedef yanlış, sendUsart fonksiyonu parametre yanlış.

fatih6761

Hocam tanımda bir sıkıntı olmuş. Hem struct tag'ine hem de type definition'a aynı ismi vermişsiniz.
Şöyle yapsak daha doğru olur sanki:
typedef struct __attribute__((packed)) {
...
...
} UsartStructVeri;

Bir de hocam kodun başında sizeof(UsartStructVeri) ile yapının gerçekte kaç bayt olduğundan emin olalım.
16 olması lazım ama öyle mi?
Bir de hocam yanlış gidiyor diyorsunuz ama alıcı taraftaki struct acaba aynı mı?
Bunun için alıcı taraftaki struct'ı da packed ayarlayıp boyutunun vericiyle aynı olduğundan emin olalım.

Bir de hocam, sendUsart fonksiyonuna struct'ı kopyalayarak atmak yerine adresini atsak daha uygun olur.
void sendUsart(UsartStructVeri *addr) {
    uint8_t *baslangic = (uint8_t*) (addr);
    int8_t sizeValue=sizeof(UsartStructVeri);
    int8_t loop;

    for(loop=0;loop<sizeValue;loop++)
        //while( !(USART1->SR & 0x00000040) );
        USART_SendData(USART1, *baslangic++);

    }


sendUsart kullanırken de sendUsart(&MyUsartStructVeri); şeklinde yapıp deneyelim.

muhittin_kaplan

#3
doğrudan terminal ile bakıyorum

mesaj birleştirme:: 23 Ağustos 2015, 20:22:45

Nerede Ne Oluyor ne bitiyor bakmak için mümkün olduğunca açık, değerleri görecek şekilde iyice açtım kodları,

fatih6761

Hocam 0xAA nın ASCI karşılığı yok bildiğim kadarıyla terminalde görünen bir karakter olmaz. HEX çıktısı varsa da hocam siz basit bir c programı yazıp veri almayı (struct'a atarak) deneyebilirsiniz.

muhittin_kaplan


fatih6761

Alıntı yapılan: muhittin_kaplan - 23 Ağustos 2015, 20:25:37
hex gözlemliyorum, o konuda problem yok.
Peki çıktı nedir hocam? Verilerde kayma mı var? yoksa eksik mi?

muhittin_kaplan

#7
kayma var, ilk bir kaçı doğru geliyor sonrasında anlamsız veriler geliyor.
şimdi array ile deneyeceğim

mesaj birleştirme:: 23 Ağustos 2015, 21:34:18

http://youtu.be/YCtqDUOMTcM

yukardaki videoda hafıza yerleşimini gösterdim
paketlenmemiş bir veriblogunda bir byte bir hafıza bloguna bir int16 diğer hafıza bloguna yerleşmesi gerekirken (kısaca her tanımlama ayrı bir hafıza bloguna)  neden int8 ile int16 yı aynı hafıza bloguna yerleştiriyor ?

yamak

Hocam aynı hafıza bloğuna yazmıyor.Orda byte olanları hafızanın 1 in katı olan yerlerine(yani herhangi bir yeri olabilir) halfword olanları da 2 nin katı olan yerlerine yazdığı için o aradaki bir byte boşluk ondan kaynaklanıyor.Yani alignment yapıyor compiler.Eğer tanımladığınız struct için alignment 1 yaparsanız bu sorun olmaz.

fatih6761

Alıntı yapılan: muhittin_kaplan - 23 Ağustos 2015, 20:36:11
kayma var, ilk bir kaçı doğru geliyor sonrasında anlamsız veriler geliyor.
şimdi array ile deneyeceğim

mesaj birleştirme:: 23 Ağustos 2015, 21:34:18

http://youtu.be/YCtqDUOMTcM

yukardaki videoda hafıza yerleşimini gösterdim
paketlenmemiş bir veriblogunda bir byte bir hafıza bloguna bir int16 diğer hafıza bloguna yerleşmesi gerekirken (kısaca her tanımlama ayrı bir hafıza bloguna)  neden int8 ile int16 yı aynı hafıza bloguna yerleştiriyor ?

Hocam derleyiciniz optimizasyon yapıyor. İşlemcinin bellek erişim komutlarıyla en hızlı veri erişimini sağlayacak şekilde struct ınızı düzenliyor.
packed ve aligned(1) yapıp deneyin. Olmazsa derleyici ayarlarından -O0 yaparak iyileştirmeleri kapatıp deneyin.

muhittin_kaplan

yok hocam baktım -O0 da

ama böyle yapması mantıklı, benim bildiğim bir yanlış sanırım. hafızayı verimli kullanmak için  eğer 32bit e sıgıyorsa oraya yerleştiriyor, eğer sığmıyorsa yeni bloga geçiyor. Bu açıdan bakarsak 4 tane byte tanımlamayı 1 bloga saklıyor. 2 16bit i yada 1 int i aynı bloga alıyor.

AsHeS

#11
-

yamak

#12
Hocam 1 byte'lık veri 1 in katı olan bölgere 2 byte'lık veri 2 nin katı olan bölgelere 4 byte lık veri 4 ün katı olan bölgelere yerleştirilir. Bırakın optimizasyonU eğer kullandığınız mikro nun unaligned memory access desteği yoksa unaligned herhangi bir erişimde mikro hardfault a düşer.Örneğin 4 ün katı olmayan bir bölgeye aşağıdaki gibi erişirseniz mikro hardfault a düşer

*(uint32_t*)0x08000001

Fakat ARM v7'de unaligned memory access desteği olduğu için ARM v7 mimarili bir mikro'da bu işlem sorun yaratmaz.Örneğin Cortex-m3 ve m4 sorun olmazken M0 ya da M0+ da hardfault oluşur..

Ayrıca optimizasyon en düşük seviyede de olsa en yüksek seviyede de olsa compiler alignment yapar. Dediğim gibi yapmazsa destek olmayan mikro'larda hardfault oluşur.