реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> IAR AVR4.30, Проблема с union
KSN
сообщение Jun 18 2009, 04:07
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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 все работает нормально. Подтвердите, это глюк компилятора?
Go to the top of the page
 
+Quote Post
Sanya_kv
сообщение Jun 18 2009, 06:06
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369



А в чем глук? у тебя все правильно работает.
А где sum.b ты присваиваешь?

Сообщение отредактировал Sanya_kv - Jun 18 2009, 06:17
Go to the top of the page
 
+Quote Post
KSN
сообщение Jun 18 2009, 06:21
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304



1. Глюк в том, что получаю 0x78,0x12,0x12,0x00 ВМЕСТО 0x78,0x12,0x01,0x00.
2. А зачем sum.b присваивать? Я уже присвоил: sum.dw = (unsigned long)0x00011278;
Go to the top of the page
 
+Quote Post
Sanya_kv
сообщение Jun 18 2009, 06:31
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369



Цитата
// далее посыдаю побайтно sum.b[0], sum.b[1],sum.b[2],sum.b[3] в CAN
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 18 2009, 06:31
Сообщение #5


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата
P.S. Скомпилировал проект под IAR AVR 5.20 все работает нормально. Подтвердите, это глюк компилятора?

Если текст один и тот же, сравните листинги и всё станет ясно.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
plombir
сообщение Jun 18 2009, 06:46
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 99
Регистрация: 14-12-05
Пользователь №: 12 191



Очень давно, в IAR3.хх с похожим столкнулся. Компилятор некорректно сдвигал вправо на большое значение кратное 8-ми. Сейчас не вспомню, с локальными или глобальными это было.
Поборол делением (data32 / 16) (data32 / 24). Что примечательно, иар не обращался к процедуре деления, а брал нужный байт как при сдвиге. Оптимизация полностью отключена.
Потом, все сдвиги заменил макросами. С ними проблем не возникало. Посмотрите, может у Вас что то похожее.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 18 2009, 07:43
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
KSN
сообщение Jun 18 2009, 09:15
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 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
 
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 18 2009, 10:54
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
plombir
сообщение Jun 18 2009, 14:30
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 99
Регистрация: 14-12-05
Пользователь №: 12 191



Цитата(Сергей Борщ @ Jun 18 2009, 11:43) *
Можно об этом подробнее?
Во глюканул, но это я хорошо разделил smile.gif
Делить нужно, соответственно, на 256, 65536, 16777216
Go to the top of the page
 
+Quote Post
KSN
сообщение Jun 19 2009, 03:02
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 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)(cool.gif; 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;
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 19 2009, 08:48
Сообщение #12


Гуру
******

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



Цитата(KSN @ Jun 19 2009, 06:02) *
TX_SET8 это макрос, вот его код
Да, в таком виде это очень похоже на баг компилятора. А можно попросить еще вывод препроцессора (Project->Options->Compiler->Preprocessor->Preprocessor output to file)?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
KSN
сообщение Jun 19 2009, 10:22
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 404
Регистрация: 3-12-04
Из: Новосибирск
Пользователь №: 1 304



Я правильно понял, это то что Вы просили?
Прикрепленный файл  OPTIONS.bmp ( 22.95 килобайт ) Кол-во скачиваний: 38
Прикрепленный файл  bootloader.7z ( 19.32 килобайт ) Кол-во скачиваний: 108
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 19 2009, 10:41
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 00:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01492 секунд с 7
ELECTRONIX ©2004-2016