C Programlama diliyle şamatalar

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

mir_as82

Sana anahtar kelime vereyim. Şimdi firmadayım ondan ayrıntılı yazamıyorum.
Struct  ile bit fields oluşturacaksın. Yazmayı ve okumayı ayrı ayrı iki makro yazıp yapacaksın.

Klein

typedef struct{
   uint8_t   count:4;
   uint8_t delay:4;
}xtype;

xtype x;

x.count = 5;
x.delay = 12;

a = x. count;
b = x. delay;

yldzelektronik

Alıntı yapılan: Klein - 06 Mayıs 2015, 12:07:30
typedef struct{
   uint8_t   count:4;
   uint8_t delay:4;
}xtype;

xtype x;

x.count = 5;
x.delay = 12;

a = x. count;
b = x. delay;

Abi bu şekilde denedim.Ancak veriler karıştı birbirine.Normalde ben de o şekilde sınırlar kullanırım diye düşündüm.Ama olmadı.

@mir_as82 bakıyorum.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

mufitsozen

Alıntı yapılan: yldzelektronik - 06 Mayıs 2015, 16:06:22
Abi bu şekilde denedim.Ancak veriler karıştı birbirine.Normalde ben de o şekilde sınırlar kullanırım diye düşündüm.Ama olmadı.

@mir_as82 bakıyorum.

veriler karisti yerine verilen ornegi kodladiginizda sonuc ne oldu soylerseniz baska bir hata yapip yapmadiginizida anlayabiliriz.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

mir_as82

#949
şunu dener misin?
a = x. count&&0x00;
b = (x. delay >> 4)&&0x00;

pardon: doğrusu bu
a = x. count&&0x0f;
b = (x. delay >> 4)&&0x0f;

yldzelektronik

#950
Alıntı yapılan: mufitsozen - 06 Mayıs 2015, 17:28:48
veriler karisti yerine verilen ornegi kodladiginizda sonuc ne oldu soylerseniz baska bir hata yapip yapmadiginizida anlayabiliriz.


Haklısınız.Afedersiniz.Debug ortamını dağıtmıştım.net ifade edebilecek kadar hatırlamadığımdan öyle yazdım.

O yapı içinde farklı değişkenler de vardı.Normalde debug ile bakarken ilgili değişkenleri gözlediğimde alması gereken değerleri alıyor.Ancak veriyi yazdıktan sonra tekrar okuduğumda farklı değerler okuyordum.O sebeple karıştı demiştim.

Ama zaten fit fields ile : kullanımı aynıymış.Bilmiyordum.
Edit: bit olacaktı o.
Alıntı yapılan: mir_as82 - 06 Mayıs 2015, 17:31:05
şunu dener misin?
a = x. count&&0x00;
b = (x. delay >> 4)&&0x00;

Neden iki && var?Anlamadım.
typedef  struct _str {
      unsigned char delay    : 4;
      unsigned char count    : 4;
 }x_t;

int main (int argc , char **argv){

     x_t x = {0x04,0x0c};
     unsigned char a = (x.delay << 4) | x.count;

      printf("a = %x", a);

      return 0 ;

}


şeklinde debug da sorun olmuyor da yazdığım yerden okuduğumda farklı değer okuyorum. Sanırım yazma veya okuma rutinleriyle ilgili problem var
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

mir_as82

#951
Hocam aceleden hata üstüne hata yapmışım :)
Haklısın. Tek & olacak.
&& olan mantıksal VE operatörü.


pardon: doğrusu bu
a = x. count&0x0f;
b = (x. delay >> 4)&0x0f;

mufitsozen

#952
mir_82'nin orneginde iki tane problem goruyorum.

1- &&, || 'logical operator'lerdir sonuclari 0 yada non-zero olur. sizin & yada | kullanmaniz lazim

2- Sizin bit fields 4 bit oldugu icin (unsigned) alabilecekleri degerler 0 ile 15 arasinda degisir!

dolayisi ile >>4 yada <<4 (delay yada count degeri ne olursa olsun) sonucu sifirdir!

tam olarak ne yapmak istiyorsunuz?




mesaj birleştirme:: 06 Mayıs 2015, 18:14:19

ucuncu bir problemde 0x00 ile & (and) operasyonu herzaman 0 sonucu verir!
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

mir_as82

hocam zaten bir alt satıra bakarsan düzelttim hata mı : )

CLR

#954
Klein'in yazdığı kısımda sorun olmaması lazım ve böyle shift vs işlemlerde de hata yapmamak için aşağıdaki şekilde kullanabilirsin

typedef struct
{
   uint8_t   count:4;
   uint8_t delay:4;
}xtype;

typedef union
{
   uint8_t Reg8;
   xtype   Nibbles;
}Regs_Typedef;

Regs_Typedef  Myregs;
uint8_t  LowByte,Hibyte,Allbyte;   

Myregs.Reg8 = 0x5A;
Allbyte = Myregs.Reg8; // Allbyte = 0x5A
LowByte = Myregs.Nibbles.count; // Lowbyte = 0xA
HiByte = Myregs.Nibbles.delay; // Hibyte = 0x5


Düzeltme :Program değişmeyecek ama küçük bir adlandırma değişikliği olursa daha iyi olur
LowByte,Hibyte ---> LowNibble,HiNibble
Knowledge and Experience are Power

mir_as82

typedef struct
{
   uint8_t   count:4;
   uint8_t delay:4;
}xtype;

Bu kodda, count değişkeninin hafiza bölgesinde düşük değerlikli nipple ya yerlesecegini nasil biliyorsunuz?

CLR

Çünkü compiler little endiansa yerleşir
Knowledge and Experience are Power

mir_as82


mufitsozen

Alıntı yapılan: CLR - 06 Mayıs 2015, 21:05:53
Çünkü compiler little endiansa yerleşir

nibblein hangisinin nereye konacagina C standard'da belirlenmemistir ve compiler'a bagimlidir. O yuzden bir computer/compiler icin calisan bit structlar baskasinda calismayabilir. Yani bit-field'lar 'portable' degildir!

Unspecified behavior

    The alignment of the addressable storage unit allocated to hold a bit-field (6.7.2.1).

Implementation-defined behavior

    Whether a bit-field can straddle a storage-unit boundary (6.7.2.1).
    The order of allocation of bit-fields within a unit (6.7.2.1).


little/big endian tabiiki compiler/computer bagimlidir!

bu yuzden ornegin linux kerneldeki iphdr struct asagidaki gibi yapilmistir:

Alıntı Yap
  struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
          __u8    ihl:4,
                     version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
          __u8    version:4,
                      ihl:4;
#else
#error  "Please fix <asm/byteorder.h>"
#endif
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

CLR

@mufitsozen,

Bu forumda konu embedded programlama olduğundan sadece bizim tanımladığımız değişkenler değil asıl işlemcinin hardware registerlerinin little/big endian olması önem arz etmekte. Yoksa sizinde örnek verdiğinizi gibi oluşturulan struct içindeki little/big endian formatı compiler direktifleri ile alt/üst edilerek kolayca seçilebilir ama hardware registerleri seçilemez (çünkü compiler'ların çoğu kolaylık olsun diye bit tanımlamalarını kendisi yapıyor, aslında özel bir struct yapılıp point edilerek yapılabilir fakat her işlemci için yeniden, işlemcinin bit hafıza haritası çıkarılması gerekir).

8-16-32bit programlamada KEIL, IAR, Microchip XCx  tipi compiler kullananların bit tanımlamaları %95'i little endian 'dır. Bu compilerlar arasında bitfield struct'lar taşınabilir ve hepsi aynı çalışır. Ama big endian formatta çalışan bir işlemci veya computer'de ters çalışır.

Mesela STM8 ile program yazarken, o işlemcinin hardware register'leri formatı big endian'dır. Dolayısıyla stm8 compiler ya big endian olması gerekir veya little/big endian seçilebilir özellikte olmalı. Ben STM8 için IAR kullandığım için o default olarak big endian formatta bit yerleştirir.
Knowledge and Experience are Power