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

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

AsHeS

Bit erişiminde sıkıntı structı packed tanımlamammış. Şöyle ki
hatalı olan bu structı
struct   Bit_Band_32_bit_s
{
	volatile uint32_t nibble0 	:4;
	volatile uint32_t nibble1 	:4;
	volatile uint32_t nibble2 	:4;
	volatile uint32_t nibble3 	:4;
	volatile uint32_t nibble4 	:4;
	volatile uint32_t nibble5 	:4;
	volatile uint32_t nibble6 	:4;
	volatile uint32_t nibble7 	:4;
};__attribute__ ((packed));


Aşağıda ki gibi tanımlanırsa problem kalmıyor

struct   Bit_Band_32_bit_s
{
	volatile uint32_t nibble0 	:4;
	volatile uint32_t nibble1 	:4;
	volatile uint32_t nibble2 	:4;
	volatile uint32_t nibble3 	:4;
	volatile uint32_t nibble4 	:4;
	volatile uint32_t nibble5 	:4;
	volatile uint32_t nibble6 	:4;
	volatile uint32_t nibble7 	:4;
};


Çözüm için yardım eden @CLR ve @gerbay a teşekkür ederim.

AsHeS

#16
Alıntı yapılan: gerbay - 26 Mart 2014, 17:19:29

text:0000000A                                 EXPORT main
.text:0000000A                         main
.text:0000000A 07 48                           LDR     R0, =0x40011004         ; Load from Memory
.text:0000000C 01 68                           LDR     R1, [R0]                ; Load from Memory
.text:0000000E 21 F4 70 61                     BIC.W   R1, R1, #0xF00          ; Rd = Op1 & ~Op2
.text:00000012 01 F5 30 61                     ADD.W   R1, R1, #0xB00          ; Rd = Op1 + Op2
.text:00000016 01 60                           STR     R1, [R0]                ; Store to Memory
.text:00000018 01 68                           LDR     R1, [R0]                ; Load from Memory
.text:0000001A 21 F4 70 21                     BIC.W   R1, R1, #0xF0000        ; Rd = Op1 & ~Op2
.text:0000001E 01 F5 30 21                     ADD.W   R1, R1, #0xB0000        ; Rd = Op1 + Op2
.text:00000022 01 60                           STR     R1, [R0]                ; Store to Memory
.text:00000024
.text:00000024                         loc_24                                  ; ...
.text:00000024 FE E7                           B       loc_24                  ; Branch
.text:00000024                         ; End of function main


estagfurullah ben birşey yapmadım...

bu şekilde LDR ve STR de erişimleri 32-bit yaptı ama ben olsam bu şekilde kod yazmazdım..
Hocam sizin derleyici Keil(MDK-ARM) galiba çünkü asm çıktıları farklı biraz (Sonu BIC.W ve ADD.W bende hiç yok :o )
Debug için yazdığım kodların çıktısı şöyle

38            USART1 -> CR1 |= USART_CR1_TE;
08000914:   ldr r3, [pc, #52]       ; (0x800094c <USART1_MyInit+304>)
08000916:   ldr r2, [pc, #52]       ; (0x800094c <USART1_MyInit+304>)
08000918:   ldrh r2, [r2, #12]
0800091a:   uxth r2, r2
0800091c:   orr.w r2, r2, #8
08000920:   uxth r2, r2
08000922:   strh r2, [r3, #12]
40            x = & USART1 -> CR1;
08000924:   ldr r3, [pc, #40]       ; (0x8000950 <USART1_MyInit+308>)
08000926:   str r3, [r7, #32]
41            x->nibble0 = 0;
08000928:   ldr r2, [r7, #32]
0800092a:   ldr r3, [r2, #0]
0800092c:   bfc r3, #0, #4
08000930:   str r3, [r2, #0]

AsHeS

Dere geçerken at değiştirmişim hocam kusuruma bakmayın özür dilerim :(

Yazım esnasında kodları ARM-GCC'ye (CooCox) taşıdım. Konu başlığını Modlardan değiştirmesini istemeyi unutmuşum.

AsHeS

#18
Alıntı yapılan: gerbay - 26 Mart 2014, 17:48:57
estagfurullah hocam..

oradaki BIC.W, ADD.W yi sadece gösterimsel olarak algılayın. 16-bit işlem yapıldığı fark edilsin diye (IDA nın içinden öyle gözüküyor).. yoksa keil ın assembly çıktısında belirtilmiyor bile, keil ın çıktısı şu şekilde;

;;;29       pReg->pin2 = 0x0B;
000004  6801              LDR      r1,[r0,#0]
000006  f4216170          BIC      r1,r1,#0xf00
00000a  f5016130          ADD      r1,r1,#0xb00
00000e  6001              STR      r1,[r0,#0]
;;;30       pReg->pin4 = 0x0B;
000010  6801              LDR      r1,[r0,#0]
000012  f4212170          BIC      r1,r1,#0xf0000
000016  f5012130          ADD      r1,r1,#0xb0000
00001a  6001              STR      r1,[r0,#0]


sizin kodda da 16-bit lik yerler var. ldrh, uxth, strh hep 16-bit işlem yapıyor.. hatta ilk önce bakınca hata buldum sandım USART1 in CR1 registerında

0800091c:   orr.w r2, r2, #8
08000920:   uxth r2, r2
08000922:   strh r2, [r3, #12]


burada 16-bit olarak store etmiş. hata sandım önce, sonra header file a baktım o register zaten 16-bit register mış..

yalnız hocam o kod debug mode kod demi? eğer release mode da o kodu üretiyorsa bence derleyici değiştirin..

Hocam debug mod optimizasyon  sıfır, aşağıda ki optimizasyonu açılmış hali
38            USART1 -> CR1 |= USART_CR1_TE;
0800064a:   ldrh r2, [r4, #12]
41            x->nibble0 = 0;
0800064c:   ldr r3, [pc, #40]       ; (0x8000678 <USART1_MyInit+208>)
38            USART1 -> CR1 |= USART_CR1_TE;
0800064e:   uxth r2, r2
08000650:   orr.w r2, r2, #8
08000654:   strh r2, [r4, #12]
41            x->nibble0 = 0;
08000656:   ldr r2, [r3, #0]


38 ve 41. satırlara sanırım optimizasyon için ayar çekmiş(Cortex M3 asm dokümanlarına bakınmaya başlamak gerek demek ki).