bit field hakkında

Peak2Peak

Aktif Üye
Katılım
27 Haziran 2020
Mesajlar
289
C:
#include <stdio.h>
#include <stdint.h>

struct date {
   int d : 4;
   int m : 4;
};

int main()
{
   uint8_t a;

   printf("Size of date is %lu bytes\n",
          sizeof(struct date));

   struct date dt = {1,3};
   printf("Date is %d/%d", dt.d, dt.m);

   a=dt.d|dt.m;
   printf("\n%d",a);

}

C 'de hiç bilmediğim yerlere bakıyordum.Bit field dedikler şeyi ile karşılaştım.Donanımda kullanılıyormuş..Bazı yerlerde kafa karıştı.
struct içinde 4 bitlik iki değişkenim var.size off ile baktığım 4 bayt tuttuğunu gördüm.4 bayt çok fazla galiba sistemden sisteme değişiyormuş.
bu bitlerin sıralamasını anlayamadım.4 bayt içinde nasıl sıralanıyor.
2 adet 4 biti or yapıp toplamayı tek bayt içinde yazmayı denedim.sonuçlar istediğim gibi çıkmadı.Bitlerin yeri aynı olunca sonuç değişmiyor.kaydırmam gerekiyor sanırım ama nasıl sıraladığını bulamadım yardımcı olabilir misin?
 
Bit field'lerin en yaygın kullanım şekli, gene bir C yapısı olan union ile birlikte kullanmaktır. Böyle bir yapı, mesela bir işlemcinin donanım registerlerine erişimi oldukça kolaylaştırır, programın da anlaşılabilirliğini arttırır. Aşağıdaki basit örneği incele. Burada bir union tanımlıyoruz. İçinde de date_int ve date_bit değişkenleri var. Buradaki union tanımı, date_int ve date_bit değişkenlerinin örtüşmesini sağlıyor. Birinde yapılan değişiklik diğerini de güncelliyor.

C:
#include <stdio.h>

union theunion
{
   unsigned int date_int;

   struct
   {
      unsigned int a : 3;
      unsigned int b : 3;
      unsigned int c : 2;

   } date_bit;
};

int main()
{
   union theunion s;

   printf("sizeof(s) = %u\n", sizeof(s));

   s.date_bit.a = 3;
   s.date_bit.b = 2;
   s.date_bit.c = 1;

   printf("s.date_int = 0x%x\n", s.date_int);

   s.date_int = 0xb3;

   printf("s.date_bit.a = %x\n", s.date_bit.a);
   printf("s.date_bit.b = %x\n", s.date_bit.b);
   printf("s.date_bit.c = %x\n", s.date_bit.c);
}
 
Aşağıda da şuanda üzerinde çalıştığım Renesas'ın RA6M2 işlemcisinin kütüphanesinden bir örnek var. Burada bir 16 bitlik bir kontrol registerinin yapısı tanımlanıyor.

C:
    union CS0CR
    {
        __IOM uint16_t CR;             /*!< (@ 0x00000002) Control Register                                           */

        struct
        {
            __IOM uint16_t EXENB : 1;  /*!< [0..0] Operation Enable                                                   */
            uint16_t             : 3;
            __IOM uint16_t BSIZE : 2;  /*!< [5..4] External Bus Width Select                                          */
            uint16_t             : 2;
            __IOM uint16_t EMODE : 1;  /*!< [8..8] Endian Mode                                                        */
            uint16_t             : 3;
            __IOM uint16_t MPXEN : 1;  /*!< [12..12] Address/Data Multiplexed I/O Interface Select                    */
            uint16_t             : 3;
        } CR_b;
    };

Bu registerin teknik dokümandaki açıklaması da şurada:
1639574586330.png


Şimdi, bir C programında ben bu kontrol registerine istediğim gibi erişebileceğim artık:

C:
int main()
{
   union CS0CR reg;

   unsigned int temp;

   /* status register read individual fields */
   temp = reg.CR_b.EXENB;
   temp = reg.CR_b.BSIZE;

   /* status registere write individual fields */
   reg.CR_b.EXENB = 1;
   reg.CR_b.BSIZE = 2;
   reg.CR_b.EMODE = 1;
   reg.CR_b.MPXEN = 1;

   /* read all fields */
   temp = REG.CR;

   /* write all fields */
   reg.CR = 0x1423;
}
 
union değişkenleri aynı hafızayı kulladığı değişimler birbirini etkiliyor sanırım
bu MSB LSB neye göre belirleniyor.
a değişkeni LSB olmuş
 
Son düzenleme:
Bit field'lerin en yaygın kullanım şekli, gene bir C yapısı olan union ile birlikte kullanmaktır. Böyle bir yapı, mesela bir işlemcinin donanım registerlerine erişimi oldukça kolaylaştırır, programın da anlaşılabilirliğini arttırır. Aşağıdaki basit örneği incele. Burada bir union tanımlıyoruz. İçinde de date_int ve date_bit değişkenleri var. Buradaki union tanımı, date_int ve date_bit değişkenlerinin örtüşmesini sağlıyor. Birinde yapılan değişiklik diğerini de güncelliyor.

C:
#include <stdio.h>

union theunion
{
   unsigned int date_int;

   struct
   {
      unsigned int a : 3;
      unsigned int b : 3;
      unsigned int c : 2;

   } date_bit;
};

int main()
{
   union theunion s;

   printf("sizeof(s) = %u\n", sizeof(s));

   s.date_bit.a = 3;
   s.date_bit.b = 2;
   s.date_bit.c = 1;

   printf("s.date_int = 0x%x\n", s.date_int);

   s.date_int = 0xb3;

   printf("s.date_bit.a = %x\n", s.date_bit.a);
   printf("s.date_bit.b = %x\n", s.date_bit.b);
   printf("s.date_bit.c = %x\n", s.date_bit.c);
}

Forumdaki eski konulara bakarken gözüme çarptı bu yanıtınız. Açıkçası kodun çıktısının neden böyle olduğunu anlayamadım. Öncelikle ben union içerisindeki en büyük hafızayı kaplayan üye kadar hafıza kaplıyor olarak biliyorum. Bu kodda structure 12 byte, int 4 byte yer kaplıyor. Union'ın hafızasının 12 byte olması gerekmez miydi ?

Bir de müsait olduğunuz bir vakitte bu kodun nasıl bu şekilde bir çıktı verdiğini anlatabilir misiniz acaba?
 
Oradaki struct "bit field", yani her değişken belli bitleri ifade ediyor. O yüzden struct'ın kapladığı byte sayısı sizeof(unsigned int) ifadesine eşittir.

Mesela programı benim linux makina için derlersem şu çıktıyı alıyorum:

Bash:
[ta@bonsai ~]$ gcc a.c
[ta@bonsai ~]$ ./a.out
sizeof(s) = 4
s.date_int = 0x53
s.date_bit.a = 3
s.date_bit.b = 6
s.date_bit.c = 2
[ta@bonsai ~]$
 

Çevrimiçi personel

Forum istatistikleri

Konular
6,956
Mesajlar
118,801
Üyeler
2,825
Son üye
karahanli7

Son kaynaklar

Son profil mesajları

hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Merhaba elektronik tutsakları...
Lyewor_ wrote on taydin's profile.
Merhabalar. Elektrik laboratuvarınız varsa bunun hakkında bir konunuz var mı acaba? Sizin laboratuvarınızı merak ettim de :)
Lyewor_ wrote on taydin's profile.
Merhabalar forumda yeniyim! Bir sorum olacaktı lcr meterler hakkında. Hem bobini ölçen hemde bobin direnci ölçen bir lcr meter var mı acaba?
Back
Top