C Programlama diliyle şamatalar

Başlatan z, 23 Ekim 2011, 15:32:04

z

Alıntı yapılan: ErsinErce - 23 Aralık 2011, 18:48:06
hocam Cortex-M3 M4 serisinde adresler ardışıl yerleşiyor diye biliyorum  ???
sf:10-11 ben mi yanlış anladım acaba?
http://www.arm.com/files/pdf/IntroToCortex-M3.pdf

Ardışıl yerleşmez. Adress Align işlemi var. Byte tipi veriler herhangi bir adrese yerleşirken 16 bit word tipi (short) veriler çift adreslere yerleşir. integer tipi 32 bit veriler ise sadece 0 ve 4 ün tam katlarına yerleşir.

Eğer C de ard arda tanımladığınız karmaşık veriler varsa (int chat char int short) bu durumda sıralamayı bozan verinin adresi yeniden hesaplanır ve arada boşluklar oluşur.

Align edilmemiş yerleşimde işlemcinin veriye ulaşım performansı düşer hatta bazı komutlar hizalanmamış verilere erişmeye kalktığında exceptiona neden olur. C derleyici buna engel olmak için verileri kendisi hizalar.

Birde eğer verileriniz arasında structure, array vs durumlar varsa hangi değişken nereye yerleşmiş bunu tahmin edemezsiniz.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

MC_Skywalker

ARM Cortex - M çekirdeğini her iki türlü (Big ve Little) tasarlıyor. Slikon üreticisi hangisini isterse onu tercih ediyor. Bunu için silkikon üreticisinin dökümanlarına bakmak gerekli.


z

Alıntı yapılan: muhittin_kaplan - 23 Aralık 2011, 19:09:18
Peki M4 chip Big mi little mi?
Little ve big olursa ne olur ?

CM3 işlemciler little endian çalışır. İstisnai olarak big endian çalışabilen çipler de varmış.  (TI Stellaris little edndian çalışıyor)

CM4 işlemcimiz de little endian çalışıyor. Fakat bunu   reset yada system init aşamasında değiştirebiliyoruz diye bir yazı okuduğumu hatırlamıyorum. Little endian bana daha mantıklı geldiği için hiç değiştirme ihtiyacı duymadım.

Çipi bigendian moduna geçirdiyseniz peripheral registerlere erişimde tekrardan little ednian moduna geçmeniz gerekir.

Fakat bu dediklerim C ile program yazanları nerede ise hiç ilgilendirmez.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

Alıntı yapılan: muhittin_kaplan - 23 Aralık 2011, 19:09:18
Peki M4 chip Big mi little mi?

Cortex™-M4 Devices Generic User Guide ( 2-10 sf:23 ) dediğine göre
Alıntı Yapmanages all data memory accesses as little-endian or big-endian. Instruction memory and
Private Peripheral Bus (PPB) accesses are always performed as little-endian.

hafıza erişimi değişebiliyor fakat diğer bölümler her zaman little endian olarak çalışıyor

@bunalmis anladım hocam teşekkürler

muhittin_kaplan

Little tamam. Yani LSB ile MSB ters.(Google dan aratınca çıkıyor hepsi de Tarihe not düşmek gerek)

1.peki bu hafıza adresleme yaparken ne olay yaratıyor?
2.her memory adresi 8 bitten oluşuyor dediniz.
peki int* P; tanımlaması yapıp A nın adresini yüklediğimizde p++ yaparsak anın adresine 1 eklemiş olacagız ve oraya 0x02 yazacağız MI ? (Yani A=0x00000201 mi olacak)

muhittin_kaplan

kafam iyice karıştı bildiğimi de unuttum :D

z

Alıntı yapılan: muhittin_kaplan - 23 Aralık 2011, 19:42:14
Little tamam. Yani LSB ile MSB ters.(Google dan aratınca çıkıyor hepsi de Tarihe not düşmek gerek)

1.peki bu hafıza adresleme yaparken ne olay yaratıyor?
2.her memory adresi 8 bitten oluşuyor dediniz.
peki int* P; tanımlaması yapıp A nın adresini yüklediğimizde p++ yaparsak anın adresine 1 eklemiş olacagız ve oraya 0x02 yazacağız MI ? (Yani A=0x00000201 mi olacak)

Diyelimki int A değişkeni 0x20000000 adresinde.

Bunu point eden int* P pointerine 0x20000000 yükledik.

Eğer p++ derseniz Pointerimiz 0x20000004 değerini alır.

-----------------

Diyelimki char A değişkeni 0x20000000 adresinde.

Bunu point eden char* P pointerine 0x20000000 yükledik.

Eğer p++ derseniz Pointerimiz 0x20000001 değerini alır.


-----------------

Diyelimki short A değişkeni 0x20000000 adresinde.

Bunu point eden short* P pointerine 0x20000000 yükledik.

Eğer p++ derseniz Pointerimiz 0x20000002 değerini alır.



-----------------

Diyelimki char A değişkeni 0x20000000 adresinde.

Bunu point eden int* P pointerine 0x20000000 yükledik.

Eğer p++ derseniz Pointerimiz 0x20000004 değerini alır.

P nin ne zaman 1 nezaman 2 ne zaman 4 artacağına derleyici karar verir. Bunu nasıl belirler pointer tanımlanırken ne diye tanımlandığına bakar.

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

tuggy



Dataların bu şekilde yerleştirileceği planlandı, yerleri reserve edildi.

0x0000 0000 nolu adrese 0x02 sayısını yazdı. A integer oldugu icin
0x0000 0001
0x0000 0002
0x0000 0003 nolu adreslerde şu an 0x00 var

Pointere A nın adresini yani 4 byte yer kaplayan A verisinin ilk adresi yükledi. Pointer da 0x0000 0000 var.

P nin değerini 1 arttırdı. P integer oldugu için 4 byte lık alana dokunmadan bir sonraki 4 byte lık alanın ilk adres değerini aldı. Yeni P değeri 0x0000 0004

Bu adres alanına 0x01 yükleyecek. Aslında yükleyeceği sayı 0x00000001. Bu 32 biti resimdeki ilk 4 byte lık bölüme A yı yerleştirdiği gibi (değersiz bitler değerli 8 er bitlik gruplardan once) yerleştirilecek. Dolayısıyla 0x0000 0004 nolu adrese 0x01 yüklenecek, 5,6 ve 7 nolu adreslere 0x00.

Tabloya bakılırsa B degeri 0x0001 olur. C ve D değerleri 0x00. A değişmez.

muhittin_kaplan

#233
yani sonuç olarak P++ dediğimizde önceden tanımlamamız aşağıdakilerden biri olduğunda
char *P yazarsak byte
Short *P yazarsak 2 Byte
int *P yazarsak 4 byte
Long *P yazarsak 8 Byte

olarak işlem yapar.
Ozaman Yukardaki sorunu cevabı B ye yazar olacak sanırım.

Peki bir soruda benden.
int    A;
short B;
char  C;
char  D;
 
int* P;
 
      A=0x02;
      P=&A;
      P++;
      *P=0xA501;

yazarsam ne olur

z

int   A;
short B;
char  C;
char  D;

int* P;

   A=0x02; 
   P=&A;               A yi point ediyoruz.
   P++;                 P 4 artti
*P=0x0101;          P, integer bir pointer olduguna gore 0x00000101 verisini A nin 4 byte otesina yazazacak

Bu durumda B ye 0x0101, C ve D ye de 0x00 yazilacaktir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ilhan_mkp

konuyla çok alakalı değil ama c ile noktalı sayıları nasıl kullanıyoruz

bascomavr ile eproma single bir değişkeni yazdığımda 4byte yazıyor (7,50) gibi

tabi basicde ne olup bitiyor bilmdiğimiz çok nokta var

birde bunalmış hocamın haricinde konuya hakim biri spi,I2C  bunları temelden anlatabilse süper olurdu

muhittin_kaplan

pnin gösterdiği adrese 16 bit yadık B yi doldurdu.
peki 32 yazsaidirk ozaman C ve D de yazılmış olacaktı bu haliyle.

int   A;
short B;
char  C;
char  D;

int* P;

   A=0x02; 
   P=&A;               A yi point ediyoruz.
   P++;                 P 4 artti
*P=0xAFB8Ad55;          P, integer bir pointer olduguna gore 0xAFB8AD55 verisini A nin 4 byte otesina yazazacak

Bu durumda B ye 0xAD55, C ye B8 ve D ye de 0xAF mi yazacaktı ?
ama anlaşına şudur ki AFB8 "B" ye diğerleri sırasıyla. big ve little olayı burada mı devreye giriyor ?

z

Alıntı yapılan: muhittin_kaplan - 23 Aralık 2011, 21:14:55
pnin gösterdiği adrese 16 bit yadık B yi doldurdu.
peki 32 yazsaidirk ozaman C ve D de yazılmış olacaktı bu haliyle.

Hayir. *P=0x0101; yazmakla aslinda siz 16 bitlik 0x0101 degil 32 bitlik 0x00000101 yazdiniz.  Cunku P integer bir pointer.
Dolayisi ile C ve D her zaman ezilecek. Daha once de dedigim gibi dikkatsizce pointer kullanimi sistemi crach edecek kadar tehlikelidir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Little endianda

0x20000000 adresine 0x12345678 yazarsak

byte larin yerlesimi su sekilde olur.

0x20000000 adresine 0x78
0x20000001 adresine 0x56
0x20000002 adresine 0x34
0x20000003 adresine 0x12


Big endian yerlesim yapilsaydi

0x20000000 adresine 0x12345678 yazarsak

byte larin yerlesimi su sekilde olur.

0x20000000 adresine 0x12
0x20000001 adresine 0x34
0x20000002 adresine 0x56
0x20000003 adresine 0x78

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

muhittin_kaplan

Hocam Bir Karışıklılık yaşıyorum.
P aslında integer bir değişken. Biz bunu Adress saklaması için Tanımlıyoruz (Pointer)
Adres 32 bitlik olabilir. Ama o adresin değeri Char,Short,Int olabilir.
int olarak tanımladığımızda P nin içereceği adres bilgisimi yoksa içeriğindeki adrese kaydedilecek bilgiyimi tanımlamış oluyoruz.
Sizin Yukarda Yazdığınıza Göre Pointer tanımı Adrese yüklenecek Değerdir.

Short *P yazacak olsaydım. yine 32 bitlik adress değerini alırmıydı ?