Перейти к содержанию
    

Кросскомпиляторный код

Вот такой вот код,

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.

 

Спасибо :)

Изменено пользователем Злодей

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот такой вот код,

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.

Спасибо :)

Можно пошагово в отладчике пройтись и узнать где начинает отличаться. Действия простые и проблем быть не должно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А результат всегда одинаковый в обоих случаях?

  {
    crc ^= byte;

Вот, например, неочевидно, чему был равен crc до этой операции

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А результат всегда одинаковый в обоих случаях?

  {
    crc ^= byte;

Вот, например, неочевидно, чему был равен crc до этой операции

Здесь всё в порядке. crc - аргумент фунции.

Изменено пользователем Злодей

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь всё в порядке. crc - аргумент фунции.

А, ну да... чё-то я парю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вчера пытался компилировать в 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 :w00t: Нашлиииии! А как починить?

if (crc & 1)
{
    crc = (crc>>1) ^ CRC32_POLYNOME;
}

 

 

Спасибо FormatCft, направил меня на путь истинный :)

Изменено пользователем Злодей

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вчера пытался компилировать в GCC без оптимизации так он отказывался...

Не может такого быть.

А он мотивировал?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот этот кусок отсутствует полностью.

Йа Станиславский :) Вы точно ходили, жмя F11 или смотрели *.lss или еще какую вредную шнягу ? :biggrin:

Objdump доведет до коровьего бешенства.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помогите, пожалуйста исправить ошибку "left shift count >= width of type"

uint32_t crc;
crc <<= 1U;

 

 

Вот такую сам вылечил

uint32_t crc;
//if (crc & ( 1 << 31 ) ) //ошибка
if (crc & ((uint32_t)1 << 31) )

 

Йа Станиславский :) Вы точно ходили, жмя F11 или смотрели *.lss или еще какую вредную шнягу ? :biggrin:

Objdump доведет до коровьего бешенства.

Так и есть, спал 2 часа, потом стоматолог дррррр, а теперь ещё и дизассембить. Извините оффтоп.

 

Что же делать "warning: left shift count >= width"

crc <<= 1U;
//uint32_t crc;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помогите, пожалуйста исправить ошибку "left shift count >= width of type"

uint32_t crc;
crc <<= 1U;

 

Простите, это уже шиза :)

В следующей строчке в константе прятался макрос, там ошибка на которую указал

Не-не-не-не..

 

uint32_t crc;
if (crc & (1UL << 31) )

 

Спасибо! Я теперь понял зачем нужны U и L :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо! Я теперь понял зачем нужны U и L :)

 

Пожалуйста. Тут с похожими граблями недавно пробегал кто-то, если указать (uint32_t)(1<<32), то он вначале 16-разрядную единицу сдвинет на 32 влево, а потом приведет к 32-разрядному. По этой причине я разлюбил пользоваться макросами типа _BV() - из-за скрытия наглядности

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот такой вот код,

.....

скомпилирован для двух платформ: BorlandCC для ПК и GCC для AVR.... На разных платформах разные результаты выполнения. Какими словами уточнить код, чтобы компиляторы наконец договорились?

В коде я никакого криминала не усмотрел...

Ещё два момента: я пока не знаю, кто из них на данный момент правильно работает. В борланде подключен \\avr\\include\\inttypes.h из WinAVR.
=8-( ) А почему используется файл от другого компилятора? За размерность типов отвечает компилятор, поэтому файл stdint.h (в котором определены типы uintXX_t и который подключается из файла inttypes.h) должен браться только из комплекта компилятора, которым осуществляется компиляция.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Часто необходимо приведение типа внутри кода (это 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).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Часто необходимо приведение типа внутри кода (это 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овский.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...