Keil'da Registerler Packed Struct'a Atanmıyor mu ?

Başlatan AsHeS, 08 Şubat 2014, 16:39:18

AsHeS

Merhaba STM32F107VC  için GPIOx_CRH registerini bit band yapmak istiyorum aşağıda ki gibi bir struct yazdım  denemelerimi tek tek anlatayım.
struct __attribute__ ((packed)) GPIO_CR_Reg_Bit_Band
{
	  uint32_t pin0 	:4;
	  uint32_t pin1 	:4;
	  uint32_t pin2 	:4;
	  uint32_t pin3 	:4;
	  uint32_t pin4 	:4;
	  uint32_t pin5 	:4;
	  uint32_t pin6 	:4;
	  uint32_t pin7 	:4;
};

Bütün denemelerde fix structım bu.
1. deneme CRH registerına doğrudan adresi ile ulaşmak
volatile struct GPIO_CR_Reg_Bit_Band *GPIO_CR_Reg_Bit;

GPIO_CR_Reg_Bit = (volatile struct GPIO_CR_Reg_Bit_Band*)&GPIOC->CRH;
GPIO_CR_Reg_Bit->pin2 = 0x0B;
GPIO_CR_Reg_Bit->pin4 = 0x0B;

Reset değeri 0x44444444 olan register ,bu işlem sonucunda şöyle oluyor. 0x4B4B4B4B
İkincisi ise aslında işi biraz daha kısaltma isteğimden kaynaklanıyor
volatile struct GPIO_CR_Reg_Bit_Band GPIO_CR_Reg_Bit;	
	memcpy(&GPIO_CR_Reg_Bit, &GPIOC->CRH, 4);

Bu denemede sevmediğim kısım memcpy gibi uzun bir fonksiyon yerine aşağıda ki gibi birşey yapılabilir mi ?(Yaptım Olmadı :( )
GPIO_CR_Reg_Bit = (struct GPIO_CR_Reg_Bit_Band)GPIOC->CRH; 

CLR

Knowledge and Experience are Power

AsHeS

#2
Alıntı yapılan: CLR - 08 Şubat 2014, 23:32:41
Burayı incele yararlı olabilir.

http://www.mcu-turkey.com/stm32f103-ozel-register-kullanimi-ve-systick/

Hocam link çare olmadı :( .

volatile struct GPIO_CR_Reg_Bit_Band GPIO_CR_Reg_Bit;

Bu değişkene normal ulaşıp 4 bit işlem yapabiliyorum. Fakat adres ile atama patlıyor.

structın tanım alanını şöyle değiştirdim.
#pragma pack(push,1)
struct Bit_Band_32_bit_s
{
  uint32_t nibble0 	:4;
  uint32_t nibble1 	:4;
  uint32_t nibble2 	:4;
  uint32_t nibble3 	:4;
  uint32_t nibble4 	:4;
  uint32_t nibble5 	:4;
  uint32_t nibble6 	:4;
  uint32_t nibble7 	:4;
}__attribute__((bitband));
#pragma pack(pop)


volatile struct Bit_Band_32_bit_s GPIO_CR_Reg_Bit;
	volatile struct Bit_Band_32_bit_s *x; 
	

	memcpy((void*)&GPIO_CR_Reg_Bit, (void*)&GPIOC->CRH, 4);


	GPIO_CR_Reg_Bit.nibble2 = 0x0B;//Debugda düzgün
	GPIO_CR_Reg_Bit.nibble4 = 0x0B;//Debugda düzgün
	x= &GPIO_CR_Reg_Bit;//Debug için koydum
	x->nibble2 = 0;//nibble4 0x0B oluyor.
	
	memcpy((void*)&GPIOC->CRH, (void*)&GPIO_CR_Reg_Bit, 4);

Adres atamada hatam var diye düşünüyorum fakat adresler debug modda baktığımda aynı.
Structı volatile ile tanımladım yinede fail verdi.

CLR

@AsHeS,

stm32 bitbanding sadece bir bit için geçerlidir, sen 4 bit için yapmaya çalışıyorsun dolayısıyla compile etsende yazdığın code bitbanding olarak çalışmaz

Knowledge and Experience are Power

AsHeS

Alıntı yapılan: CLR - 09 Şubat 2014, 11:55:45
@AsHeS,

stm32 bitbanding sadece bir bit için geçerlidir, sen 4 bit için yapmaya çalışıyorsun dolayısıyla compile etsende yazdığın code bitbanding olarak çalışmaz
Hocam bahsettiğiniz şey sadece registerler için mi geçerli ?
struct tipinde stackte normal değişken tanımlarsam 4-bit 4-bit  değişim yapabiliyorum .

z

Bit banding tek bit uzerinde islem yapar. Register yada memory farketmez.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

AsHeS

#6
Alıntı yapılan: z - 09 Şubat 2014, 15:41:58
Bit banding tek bit uzerinde islem yapar. Register yada memory farketmez.
Hocam adını değiştirelim o zaman 4-Bit Banding(bit fields) diyelim stack'te açtığım değişkende oluyorda register adresini aldığım da neden olmuyor bunu çözemiyorum adresi yanlış alıyorum diye düşünmüye başladım artık.

Eğer stackte açtığımda değişkeni pointer  ile değiştirirsem sıkıntı olmuyor. Örnek
  volatile struct Bit_Band_32_bit_s  k;
  volatile struct Bit_Band_32_bit_s *x; 
  
	memset(&k, NULL, sizeof(k));
	
	k.nibble0 = 4;
	k.nibble1 = 2;
	
	x = &k;
	x->nibble3 = 1;
	x->nibble4 = 4;
	x->nibble5 = 3;


İşlem sonucunda sayı 42143000 oluyor sıkıntı çıkmıyor fakat registerın adresini almaya kalkarsam birşeyler ters gidiyor.
Yani   x = (volatile struct Bit_Band_32_bit_s *)&GPIOC->CRH;   yaptıktan sonra x->nibble3 = 1; dersem işler istediğim gibi gitmiyor.



AsHeS


CLR

Aşağıdaki şekilde yapabilirsin

typedef volatile struct TIM_REGS 		TimStructType;

void TmrxInit(u32 TmrxBase,u16 ms,u16 time_sbt,u8 UseInt)
{
    TimStructType *Tmrx=(TimStructType *)TmrxBase;
    Tmrx->arr.W32=ms;
    Tmrx->psc.W32=time_sbt;

Knowledge and Experience are Power

AsHeS

Alıntı yapılan: CLR - 24 Mart 2014, 11:38:51
Aşağıdaki şekilde yapabilirsin

typedef volatile struct TIM_REGS 		TimStructType;

void TmrxInit(u32 TmrxBase,u16 ms,u16 time_sbt,u8 UseInt)
{
    TimStructType *Tmrx=(TimStructType *)TmrxBase;
    Tmrx->arr.W32=ms;
    Tmrx->psc.W32=time_sbt;

8/16/32 bit değilde 1-2-3-4-5-6-7 bit olarak erişmek istiyorum alanlara. hiç denediniz  mi o şekilde ulaşmayı ?

z

Bitbanding erişim yaparken registerin fiziksel (8/16/32 bit erişim) adresini aynen mi kullanıyorsun?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

AsHeS

Alıntı yapılan: z - 24 Mart 2014, 14:46:49
Bitbanding erişim yaparken registerin fiziksel (8/16/32 bit erişim) adresini aynen mi kullanıyorsun?
Hocam üstte ki mesajlarımda başarısız denemelerimi yazdım. Telden girdiğim için copy paste etmek zor biraz :(

CLR

evet çok kullandım, aşağıda örnek var

void TmrxInit(u32 TmrxBase,u16 ms,u16 time_sbt,u8 UseInt)
{
    TimStructType *Tmrx=(TimStructType *)TmrxBase;
    Tmrx->arr.W32=ms;
    Tmrx->psc.W32=time_sbt;
//    Tmrx->cr1.Bits.CKD=0;
//    Tmrx->cr1.Bits.DIR=0;
    Tmrx->egr.Bits.UG=1;
    Tmrx->sr.Bits.UIF=0;
Knowledge and Experience are Power

AsHeS

#13
Alıntı yapılan: CLR - 24 Mart 2014, 15:43:39
evet çok kullandım, aşağıda örnek var

void TmrxInit(u32 TmrxBase,u16 ms,u16 time_sbt,u8 UseInt)
{
    TimStructType *Tmrx=(TimStructType *)TmrxBase;
    Tmrx->arr.W32=ms;
    Tmrx->psc.W32=time_sbt;
//    Tmrx->cr1.Bits.CKD=0;
//    Tmrx->cr1.Bits.DIR=0;
    Tmrx->egr.Bits.UG=1;
    Tmrx->sr.Bits.UIF=0;


Sizin daha önce verdiğiniz koddan hareketle şunu yazdım(gcc ile)
volatile struct  Bit_Band_16_bit_s
{
	volatile uint16_t nibble0 	:4;
    	volatile uint16_t nibble1 	:4;
	volatile uint16_t nibble2 	:4;
        volatile uint16_t nibble3 	:4;
}__attribute__ ((packed));

volatile struct Bit_Band_16_bit_s *x;

    x = &(USART1 -> CR1);

    x->nibble1 = 1;


USART1 -> CR1  içerdiği değer 0x2008 ,
x->nibble1 = 1 ,satırından sonra 0x1818 burada neden böyle oluyor sorum aslında bu?


AsHeS

@gerbay
eyv. hocam aydınlattığınız çok sağolun.