Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR AVR4.30
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
KSN
Пишу загрузчик для 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 все работает нормально. Подтвердите, это глюк компилятора?
Sanya_kv
А в чем глук? у тебя все правильно работает.
А где sum.b ты присваиваешь?
KSN
1. Глюк в том, что получаю 0x78,0x12,0x12,0x00 ВМЕСТО 0x78,0x12,0x01,0x00.
2. А зачем sum.b присваивать? Я уже присвоил: sum.dw = (unsigned long)0x00011278;
Sanya_kv
Цитата
// далее посыдаю побайтно sum.b[0], sum.b[1],sum.b[2],sum.b[3] в CAN
MrYuran
Цитата
P.S. Скомпилировал проект под IAR AVR 5.20 все работает нормально. Подтвердите, это глюк компилятора?

Если текст один и тот же, сравните листинги и всё станет ясно.
plombir
Очень давно, в IAR3.хх с похожим столкнулся. Компилятор некорректно сдвигал вправо на большое значение кратное 8-ми. Сейчас не вспомню, с локальными или глобальными это было.
Поборол делением (data32 / 16) (data32 / 24). Что примечательно, иар не обращался к процедуре деления, а брал нужный байт как при сдвиге. Оптимизация полностью отключена.
Потом, все сдвиги заменил макросами. С ними проблем не возникало. Посмотрите, может у Вас что то похожее.
Сергей Борщ
Цитата(plombir @ Jun 18 2009, 09:46) *
Потом, все сдвиги заменил макросами.
Можно об этом подробнее?
KSN: показывайте листинги.
KSN
Прилагаю файлы iar430a.7z и iar520.7z
В первом листинг, map, файл исходника с функцией main.c и *.xcl файл.
Во втором только листинг и map.Нажмите для просмотра прикрепленного файлаНажмите для просмотра прикрепленного файла
Сергей Борщ
Цитата(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
plombir
Цитата(Сергей Борщ @ Jun 18 2009, 11:43) *
Можно об этом подробнее?
Во глюканул, но это я хорошо разделил smile.gif
Делить нужно, соответственно, на 256, 65536, 16777216
KSN
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;
Сергей Борщ
Цитата(KSN @ Jun 19 2009, 06:02) *
TX_SET8 это макрос, вот его код
Да, в таком виде это очень похоже на баг компилятора. А можно попросить еще вывод препроцессора (Project->Options->Compiler->Preprocessor->Preprocessor output to file)?
Сергей Борщ
Цитата(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)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.