|
Кросскомпиляторный код, BCC и GCC |
|
|
|
Apr 30 2009, 07:41
|

Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142

|
Вот такой вот код, Код inline uint32_t crc32_add( uint32_t crc, uint8_t byte ) { crc ^= byte; for (uint8_t i=0; i<8; i++) { if (crc & 1) { crc = (crc>>1) ^ CRC32_POLYNOME; } else { crc >>= 1; } } return crc; } скомпилирован для двух платформ: BorlandCC для ПК и GCC для AVR.... На разных платформах разные результаты выполнения. Какими словами уточнить код, чтобы компиляторы наконец договорились? Ещё два момента: я пока не знаю, кто из них на данный момент правильно работает. В борланде подключен \\avr\\include\\inttypes.h из WinAVR. Спасибо
Сообщение отредактировал Злодей - Apr 30 2009, 07:47
|
|
|
|
|
Apr 30 2009, 07:44
|

Местный
  
Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145

|
Цитата(Злодей @ Apr 30 2009, 13:41)  Вот такой вот код, Код inline uint32_t crc32_add( uint32_t crc, uint8_t byte ) { crc ^= byte; for (uint8_t i=0; i<8; i++) { if (crc & 1) { crc = (crc>>1) ^ CRC32_POLYNOME; } else { crc >>= 1; } } return crc; } скомпилирован для двух платформ: BorlandCC для ПК и GCC для AVR.... На разных платформах разные результаты выполнения. Какими словами уточнить код, чтобы компиляторы наконец договорились? Я пока не знаю, кто из них на данный момент правильно работает. В борланде подключен \\avr\\include\\inttypes.h из WinAVR. Спасибо  Можно пошагово в отладчике пройтись и узнать где начинает отличаться. Действия простые и проблем быть не должно.
|
|
|
|
|
Apr 30 2009, 08:09
|

Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142

|
Цитата(MrYuran @ Apr 30 2009, 12:03)  А результат всегда одинаковый в обоих случаях? Код { crc ^= byte; Вот, например, неочевидно, чему был равен crc до этой операции Здесь всё в порядке. crc - аргумент фунции.
Сообщение отредактировал Злодей - Apr 30 2009, 08:10
|
|
|
|
|
Apr 30 2009, 08:47
|

Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142

|
Вчера пытался компилировать в GCC без оптимизации так он отказывался... Ставил везде-везде volatile - не помогало. В AVR Studio видно, что осталось от кода: Код uintX_t crc32_add( uintX_t crc, uint8_t byte ) { crc ^= byte; uint8_t i = 8; do { crc >>= 1; } while(--i);
return crc; } Вот этот кусок отсутствует полностью. Типа младший бит всегда 0  Нашлиииии! А как починить? Код if (crc & 1) { crc = (crc>>1) ^ CRC32_POLYNOME; } Спасибо FormatCft, направил меня на путь истинный
Сообщение отредактировал Злодей - Apr 30 2009, 08:54
|
|
|
|
|
Apr 30 2009, 09:46
|

Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142

|
Помогите, пожалуйста исправить ошибку "left shift count >= width of type" Код uint32_t crc; crc <<= 1U; Вот такую сам вылечил Код uint32_t crc; //if (crc & ( 1 << 31 ) ) //ошибка if (crc & ((uint32_t)1 << 31) ) Цитата(_Pasha @ Apr 30 2009, 13:40)  Йа Станиславский  Вы точно ходили, жмя F11 или смотрели *.lss или еще какую вредную шнягу ?  Objdump доведет до коровьего бешенства. Так и есть, спал 2 часа, потом стоматолог дррррр, а теперь ещё и дизассембить. Извините оффтоп. Что же делать "warning: left shift count >= width" Код crc <<= 1U; //uint32_t crc;
|
|
|
|
|
Apr 30 2009, 10:04
|

Частый гость
 
Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142

|
Цитата(Злодей @ Apr 30 2009, 13:46)  Помогите, пожалуйста исправить ошибку "left shift count >= width of type" Код uint32_t crc; crc <<= 1U; Простите, это уже шиза  В следующей строчке в константе прятался макрос, там ошибка на которую указал Цитата(_Pasha @ Apr 30 2009, 13:46)  Не-не-не-не.. Код uint32_t crc; if (crc & (1UL << 31) ) Спасибо! Я теперь понял зачем нужны U и L
|
|
|
|
|
Apr 30 2009, 12:19
|

Местный
  
Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091

|
Цитата(Злодей @ Apr 30 2009, 12:41)  Вот такой вот код, ..... скомпилирован для двух платформ: BorlandCC для ПК и GCC для AVR.... На разных платформах разные результаты выполнения. Какими словами уточнить код, чтобы компиляторы наконец договорились? В коде я никакого криминала не усмотрел... Цитата(Злодей @ Apr 30 2009, 12:41)  Ещё два момента: я пока не знаю, кто из них на данный момент правильно работает. В борланде подключен \\avr\\include\\inttypes.h из WinAVR. =8-( ) А почему используется файл от другого компилятора? За размерность типов отвечает компилятор, поэтому файл stdint.h (в котором определены типы uintXX_t и который подключается из файла inttypes.h) должен браться только из комплекта компилятора, которым осуществляется компиляция.
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
|
Apr 30 2009, 13:05
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Часто необходимо приведение типа внутри кода (это CRC8): Код char wk_crc8_block(const char *datablock, const unsigned int count_byte) {
register unsigned int count; char crc1, ch; crc1 = (char)CRC_WAKE_INIT; for(count = 0; count < count_byte; count++) { ch = (char)datablock[count]; Do_Crc8(ch, &crc1); } crc1 = (char)crc1; return(crc1); }
void Do_Crc8(char b, char *crc) { int i; for (i = 0; i < 8; i++) { if (((b ^ *crc) & 1) != 0) *crc = (char)(((*crc ^ 0x18) >> 1) | 0x80); else *crc = (char)((*crc >> 1) & ~0x80); b = (char)(b >> 1); } } Без явного приведения типа к (char) для AVR -все в порядке, а на PC и freescale MC56F8346 полный бред. Компилятор любит использовать размер данные "родной" для платформы (AVR - 8 бит, Freescale - 16, PC - 32).
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Apr 30 2009, 14:49
|
Местный
  
Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112

|
Цитата(mdmitry @ Apr 30 2009, 19:05)  Часто необходимо приведение типа внутри кода (это CRC8): Код char wk_crc8_block(const char *datablock, const unsigned int count_byte) {
register unsigned int count; char crc1, ch; crc1 = (char)CRC_WAKE_INIT; for(count = 0; count < count_byte; count++) { ch = (char)datablock[count]; Do_Crc8(ch, &crc1); } crc1 = (char)crc1; return(crc1); }
void Do_Crc8(char b, char *crc) { int i; for (i = 0; i < 8; i++) { if (((b ^ *crc) & 1) != 0) *crc = (char)(((*crc ^ 0x18) >> 1) | 0x80); else *crc = (char)((*crc >> 1) & ~0x80); b = (char)(b >> 1); } } Без явного приведения типа к (char) для AVR -все в порядке, а на PC и freescale MC56F8346 полный бред. Компилятор любит использовать размер данные "родной" для платформы (AVR - 8 бит, Freescale - 16, PC - 32). Тут проблема может быть в другом, и явное приведение типа вовсе ни при чём. По стандарту не оговаривается чётко, должен быть беззнаковым тип char или иметь знак. Поэтому поведение такого кода может изменятся даже для одного и того же целевого процессора, в зависимости от ключей компиляции, а уж при переходе от одной платформы к другой - и подавно. Вот и получается, что для AVR char может быть беззнаковым - и всё в порядке, а на PC и Freescale char имеет знак - и получается полный бред. В таких случаях и надо использовать стандартный восьмибитный беззнаковый тип - uint8_t (который в большинстве случаев, но опять же не всегда - unsigned char). ЗЫ. А stdint.h надо брать тот, который идёт с компилятором, а не из чужой среды, т. е. для борланда - борландский, для AVR - avrовский.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|