|
|
  |
IAR AVR4.30, Проблема с union |
|
|
|
Jun 18 2009, 04:07
|
Местный
  
Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304

|
Пишу загрузчик для AT90CAN128 и столкнулся с проблемой. Далее привожу часть кода, которая вызывает ошибку. __C_task main(void) { // обявил переменную sum union { unsigned char b[4]; unsigned int w[2]; unsigned long dw; }sum; unsigned long data32; sum.dw = (unsigned long)0x00011278; // далее посыдаю побайтно sum.b[0], sum.b[1],sum.b[2],sum.b[3] в CAN data32 = (unsigned long)0x00011278; // далее посыдаю побайтно (unsigned char)data32, (unsigned char)(data32>>8), // (unsigned char)(data32>>16),(unsigned char)(data32>>24) в CAN }
В результате вижу по CAN: 1-ая посылка: 0x78, 0x12, 0x12, 0x00 2-ая: 0x78, 0x12, 0x01, 0x00 В чем глюк понять не могу. Это клюк компилятора или я что-то не так делаю? Уровень оптимизации стоит максимальный по объему кода. P.S. Скомпилировал проект под IAR AVR 5.20 все работает нормально. Подтвердите, это глюк компилятора?
|
|
|
|
|
Jun 18 2009, 07:43
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(plombir @ Jun 18 2009, 09:46)  Потом, все сдвиги заменил макросами. Можно об этом подробнее? KSN: показывайте листинги.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 18 2009, 09:15
|
Местный
  
Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304

|
Прилагаю файлы iar430a.7z и iar520.7z В первом листинг, map, файл исходника с функцией main.c и *.xcl файл. Во втором только листинг и map.
Iar430a.7z ( 28.07 килобайт )
Кол-во скачиваний: 130
Iar520.7z ( 24.56 килобайт )
Кол-во скачиваний: 156
Прикрепленные файлы
Iar430a.7z ( 28.07 килобайт )
Кол-во скачиваний: 17
|
|
|
|
|
Jun 18 2009, 10:54
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(KSN @ Jun 18 2009, 12:15)  Прилагаю файлы iar430a.7z и iar520.7z Покажите исходник TX_SET8, возможно проблема в нем. Пока видно вот что: Код 120 sum.dw = *((Uint32 __hugeflash *)(0x0000A2)); \ 0000008E EAE2 LDI R30, 162 \ 00000090 E0F0 LDI R31, 0 \ 00000092 BFFB OUT 0x3B, R31 \ 00000094 9187 ELPM R24, Z+ \ 00000096 9197 ELPM R25, Z+ \ 00000098 91A7 ELPM R26, Z+ \ 0000009A 91B6 ELPM R27, Z 121 data32 = *((Uint32 __hugeflash *)(0x0000A2)); Это чтение. Компилятор соптимизировал обе переменные в одну. Далее развернут и встроен TX_SET8.
Это обработка одной копии: \ ??CrossCallReturnLabel_28: \ 0000009E 8786 STD Z+14, R24 \ 000000A0 8797 STD Z+15, R25 \ 000000A2 8BA0 STD Z+16, R26 \ 000000A4 8BB1 STD Z+17, R27 Это обработка второй. Дважды используется один байт из R25: \ 00000000 8B82 STD Z+18, R24 \ 00000002 8B93 STD Z+19, R25 \ 00000004 8B94 STD Z+20, R25 \ 00000006 8BB5 STD Z+21, R27
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 18 2009, 14:30
|
Частый гость
 
Группа: Участник
Сообщений: 99
Регистрация: 14-12-05
Пользователь №: 12 191

|
Цитата(Сергей Борщ @ Jun 18 2009, 11:43)  Можно об этом подробнее? Во глюканул, но это я хорошо разделил  Делить нужно, соответственно, на 256, 65536, 16777216
|
|
|
|
|
Jun 19 2009, 03:02
|
Местный
  
Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304

|
TX_SET8 это макрос, вот его код #define TX_SET8(a,b,c,d,e,f,g,h,i,j) Can_Tx.cmd = a; Can_Tx.id.ext = (Uint32)(  ; Can_Tx.ctrl.ide = 1;\ Can_Tx.dlc = 8; Can_Tx.data[0] = c; Can_Tx.data[1] = d;\ Can_Tx.data[2] = e; Can_Tx.data[3] = f; Can_Tx.data[4] = g;\ Can_Tx.data[5] = h; Can_Tx.data[6] = i; Can_Tx.data[7] = j; Заодно привожу и описание Can_Tx: typedef enum { CMD_NONE, CMD_TX, CMD_TX_DATA, CMD_TX_REMOTE, CMD_TX_INT, CMD_TX_DATA_INT, CMD_TX_REMOTE_INT, CMD_RX, CMD_RX_DATA, CMD_RX_REMOTE, CMD_RX_MASKED, CMD_RX_DATA_MASKED, CMD_RX_REMOTE_MASKED, CMD_RX_INT, CMD_RX_DATA_INT, CMD_RX_REMOTE_INT, CMD_RX_MASKED_INT, CMD_RX_DATA_MASKED_INT, CMD_RX_REMOTE_MASKED_INT, CMD_REPLY, CMD_REPLY_MASKED, CMD_REPLY_INT, CMD_REPLY_MASKED_INT, CMD_ABORT } can_cmd_t; // ---------- typedef union{ Uint32 ext; Uint16 std; Uint8 tab[4]; } can_id_t; // ---------- typedef struct{ Bool rtr; Bool ide; } can_ctrl_t; typedef struct{ Uint8 handle; can_cmd_t cmd; can_id_t id; can_id_t mask; Uint8 dlc; // Uint8* pt_data; Uint8 status; can_ctrl_t ctrl; Uint8 data[8]; } st_cmd_t;
|
|
|
|
|
Jun 19 2009, 10:41
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(KSN @ Jun 19 2009, 13:22)  Я правильно понял, это то что Вы просили? Да, совершенно правильно. Вот во что препроцессор развернул макрос (я вставил переводы строки для читаемости): Код sum.dw = *((Uint32 __hugeflash *)(0x0000A2)); data32 = *((Uint32 __hugeflash *)(0x0000A2)); Can_Tx . cmd = CMD_TX_DATA; Can_Tx . id . ext = (Uint32)(0x10000000|(((Uint32)0x0051<<13))|((Uint32)0x0000)); Can_Tx . ctrl . ide = 1; Can_Tx . dlc = 8; Can_Tx . data[0] = (Uint8)data32; Can_Tx . data[1] = (Uint8)(data32>>8); Can_Tx . data[2] = (Uint8)(data32>>16); Can_Tx . data[3] = (Uint8)(data32>>24); Can_Tx . data[4] = sum . b[0]; Can_Tx . data[5] = sum . b[1]; Can_Tx . data[6] = sum . b[2]; Can_Tx . data[7] = sum . b[3]; Очевидно, что компилятор получил правильные данные. Значит - таки да, бага. Совет: во избежание неожиданностей в ситуациях типа if(...) TX_SET8; оберните тело TX_SET8 и подобных в do { ... } while(0)
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|