Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Баг компилятора RVCT 4.0
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
fantex
Обнаружилась одна неприятность с данным компилятором. Имеется следующий код:
CODE


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

struct DataPointer
{
union
{
__packed void *v;
__packed byte *b;
__packed word *w;
__packed dword *d;
__packed float *f;
};

DataPointer(__packed void *p) { v = p; }
DataPointer(__packed byte *p) { b = p; }
DataPointer(__packed word *p) { w = p; }
DataPointer(__packed dword *p) { d = p; }
DataPointer(__packed float *p) { f = p; }

void operator=(__packed void *p) { v = p; }
void operator=(__packed byte *p) { b = p; }
void operator=(__packed word *p) { w = p; }
void operator=(__packed dword *p) { d = p; }
void operator=(__packed float *p) { f = p; }
};

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

bool ReadEvent(word startAdr, word count, DataPointer data)
{
const u32 *p = dd + st;

for ( ; c > 0; c--)
{
*(data.d++) = *(p++);
};

return true;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



При компиляции с выключеной оптимизацией или с оптимизацией по размеру -Ospace, всё работает нормально. Но при включеной оптимизацией по времени -Otime, вываливается в Abort, так как указатель в data указывает на не выровненый адрес.

Листинг при отключеной оптимизации.
CODE

00008a 6980 LDR r0,[r0,#0x18] ;69
00008c 0089 LSLS r1,r1,#2 ;69
00008e 1845 ADDS r5,r0,r1 ;69
000090 001e MOVS r6,r3 ;70
000092 e006 B |L1.162|
|L1.148|
000094 6828 LDR r0,[r5,#0] ;74
000096 0031 MOVS r1,r6 ;74
000098 f7fffffe BL __aeabi_uwrite4
00009c 1d2d ADDS r5,r5,#4 ;74
00009e 1d36 ADDS r6,r6,#4 ;74
0000a0 1e64 SUBS r4,r4,#1 ;72
|L1.162|
0000a2 2c00 CMP r4,#0 ;72
0000a4 dcf6 BGT |L1.148|


Листинг при включеной оптимизации по времени.
CODE

0000a4 6842 LDR r2,[r0,#4] ;71
0000a6 1061 ASRS r1,r4,#1 ;71
0000a8 d007 BEQ |L1.186|
|L1.170|
0000aa 3008 ADDS r0,r0,#8
0000ac 6804 LDR r4,[r0,#0] ;73
0000ae 605a STR r2,[r3,#4] ;73
0000b0 6842 LDR r2,[r0,#4] ;73
0000b2 609c STR r4,[r3,#8] ;73
0000b4 3308 ADDS r3,r3,#8 ;73
0000b6 1e49 SUBS r1,r1,#1 ;73
0000b8 d1f7 BNE |L1.170|



Вылечилось всё это следующим образом:

CODE

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

bool ReadEvent(word startAdr, word count, DataPointer data)
{
const u32 *p = dd + st;
__packed u32 *d = data.d;

for ( ; c > 0; c--)
{
*(d++) = *(p++);
};

return true;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


И листинг:

CODE

000088 6980 LDR r0,[r0,#0x18] ;69
00008a 0092 LSLS r2,r2,#2 ;69
00008c 1882 ADDS r2,r0,r2 ;69
00008e 2900 CMP r1,#0 ;72
000090 dd0b BLE |L1.170|
|L1.146|
000092 ca01 LDM r2!,{r0} ;74
000094 1e49 SUBS r1,r1,#1 ;74
000096 0a04 LSRS r4,r0,#8 ;74
000098 7018 STRB r0,[r3,#0] ;74
00009a 705c STRB r4,[r3,#1] ;74
00009c 0c04 LSRS r4,r0,#16 ;74
00009e 0e00 LSRS r0,r0,#24 ;74
0000a0 709c STRB r4,[r3,#2] ;74
0000a2 70d8 STRB r0,[r3,#3] ;74
0000a4 1d1b ADDS r3,r3,#4 ;74
0000a6 2900 CMP r1,#0 ;74
0000a8 dcf3 BGT |L1.146|


Версия компилятора RVCT 4.0 build 697
demiurg_spb
Возможно, Вы неверно используете __packed. Возможно, я не понял чего вы добиваетесь ("умные" указатели на упакованные типы?).
Я обычно (редко бывает нужно) использую атрибут packed (в gcc) для указания шага выравнивания полей структуры:
Код
typedef struct __packed
{
    uint8_t  a;
    uint16_t b;
    uint32_t c;
    ....
} my_type_t;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.