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

Вычисление CRC с помощью sRecord

Доброго всем времени суток!

Задача: есть исходный файл (бинарник) из 8 байт, забитых значением 0x11. Надо в конец файла (т.е. с адреса 0x08) вставить 2 байта CRC16 (вычисленное с полиномом 0xA001) программой Srecord. Делаю так:

srec_cat sec.bin --binary -crc16-b-e 0x08 -poly 0xA001 --output sec_new.bin --binary

Значения добавляются (0x14 0x1E), но не те (0xED 0xE7).

В чем может быть проблема? Может srecord нужно указывать начало и конец исходных данных?

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


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

С полиномом 0xA001 сдвиг осуществляется вправо. "crc16-b-e" как бы намекает на сдвиг влево. Попробуйте crc16-l-e, хоть я такого в документации и не нашел (но я там и crc16-b-e нашел только в примерах).

 

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


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

С полиномом 0xA001 сдвиг осуществляется вправо. "crc16-b-e" как бы намекает на сдвиг влево. Попробуйте crc16-l-e, хоть я такого в документации и не нашел (но я там и crc16-b-e нашел только в примерах).

Пробовал эту команду - выходные байты просто меняются местами (0x1E 0x14). Мне кажется здесь дело либо в неправильном указании границ данных, либо в указании формата (--binary).

Изменено пользователем Sprite

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


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

Пользовался только "стандартным" CRC, так что мысли чисто теоретические, но...

 

Документация сообщает нам, что значение полинома надо передавать просто числом, без -poly. Ключ poly - это ИМЯ полинома.

 

Сергей, crc16-l-e / -b-e в документации есть (http://srecord.sourceforge.net/man/man1/srec_input.html, искать "crc16"). Другой вопрос, что документации могло бы быть и побольше, без чЮдных фразочек "и вообще, это опенсорс, смотрите в исходниках".

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


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

Документация сообщает нам, что значение полинома надо передавать просто числом, без -poly. Ключ poly - это ИМЯ полинома.

Да, но я пробовал делать так: указал полином ccitt в качестве параметра, получил результат (0xCE 0x79), затем нашел в описание, посмотрел значение полинома для ccitt (0x1021) и подставил 0x1021 вместо ccitt - результат получился тот же. Из чего я сделал вывод, что полином можно скармливать любой в hex-формате, а не только в виде строковых значений (asci, modbus, ccitt и т.д.).

Изменено пользователем Sprite

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


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

Сергей, crc16-l-e / -b-e в документации есть (http://srecord.sourceforge.net/man/man1/srec_input.html, искать "crc16").
Спасибо. Я искал именно "crc16-b-e", а там описана полная форма "−CRC16_Big_Endian". "Догадайся, мол, сама". Там есть и описание двух ключей - "−Most_To_Least" (по умолчанию) и "−Least_To_Most", который, вероятно, нам и нужен.

 

 

 

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


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

Спасибо. Я искал именно "crc16-b-e", а там описана полная форма "−CRC16_Big_Endian". "Догадайся, мол, сама". Там есть и описание двух ключей - "−Most_To_Least" (по умолчанию) и "−Least_To_Most", который, вероятно, нам и нужен.

Попробовал -Least_To_Most:

srec_cat sec.bin --binary -crc16-b-e 0x08 -Least_To_Most -poly 0xA001 --output sec_new.bin --binary

Результат получается другой (0x45 0xC7), но не правильный (

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


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

Пока разберетесь с документацией, проще самому в GCC написать короткую консольную программу.

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


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

Да, но я пробовал делать так: указал полином ccitt в качестве параметра, получил результат (0xCE 0x79), затем нашел в описание, посмотрел значение полинома для ccitt (0x1021) и подставил 0x1021 вместо ccitt - результат получился тот же.

srecord использует CCITT по умолчанию, так что результат эксперимента, скорее всего, получился некорректный.

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


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

Пока разберетесь с документацией, проще самому в GCC написать короткую консольную программу.

Ну да, может Вы и правы ;) Я пишу загрузчик, точнее уже написал. Просто хочется добавить в него CRC и сделать какое-нибудь шифрование прошивки. Люди посоветовали для этих целей использовать Srecord - там уже есть все возможности - решил не изобретать велосипед. Да и программа мне нравится - только вот работает пока не так как надо ;)

 

srecord использует CCITT по умолчанию, так что результат эксперимента, скорее всего, получился некорректный.

При изменении значения полинома (0x1021) меняется конечный результат.

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


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

Пробовал считать CRC32. Код такой:

srec_cat sec.bin --binary -crc32-b-e 0x08 --output sec_new.bin --binary

Результат получился 0x4DB8ECF5. Нашел онлайн калькулятор CRC - результат совпал. Но попробовал посчитать то же самое на stm - не вышло, считал как программным, так и аппаратным методом - в обоих методах результат одинаковый (0xEC5DBEA0)

//===================================================================
uint32_t sw_calculate_soft_crc(uint32_t *pinput, uint32_t length)
{
    uint32_t initial_crc = 0xFFFFFFFF; // начальное значение                 
    uint32_t* input_data = pinput;
    uint32_t polynom     = 0x4C11DB7; // полином
    uint32_t crc         = 0        ; // контрольная сумма
    uint32_t index       = 0;          
    uint32_t bindex      = 0;

    while( index<length )
    {
    if(index==0){   crc = initial_crc ^ input_data[index];}
    else        {   crc = crc ^ input_data[index];        }

        while(   bindex<(sizeof(input_data[index])*8)   )
        {    // if MSB of CRC = 1
            if((crc>>31)==1){crc=(crc<<1)^polynom;}
            else            {crc=(crc<<1);        }
            bindex++;
        }

    bindex=0;
    index++;
    }

    return crc;
}

//===================================================================
uint32_t sw_calculate_crc(uint32_t *input_data, uint32_t length)
{
    // присваиваем адрес начала данных
    uint32_t* pBuffer    = input_data;
    uint32_t index      = 0;
    uint32_t result     = 0;

    __CRC_CLK_ENABLE();             //Включить тактирование
    CRC->CR = CRC_CR_RESET;         //Сброс контрольного регистра

    while(index<length)                //Запись данных в регистр данных для расчета
    {
        CRC->DR = pBuffer[index++];
        tmp++;
    }

    result = CRC->DR;                //Извлечь просчитаную контрольную сумму
    __CRC_CLK_DISABLE();               //Выключить тактирование                      
    return result;
}

А вот, собственно, вызов функций:

    uint32_t CRC_val = 0;
    uint32_t CRC_val2 = 0;    
    uint32_t data_table[]={0x11111111,0x11111111};    
    
    CRC_val = sw_calculate_crc(data_table, sizeof(data_table)/sizeof(uint32_t));
    CRC_val2= sw_calculate_soft_crc(data_table, sizeof(data_table)/sizeof(uint32_t));

Вопрос по прежнему открыт.

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


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

Может быть, расскажете, как правильно?

Чтобы значение CRC в srecord совпадало с расчетами CRC stm32 нужно использовать ключ -STM32_Big_Endian

::вычисляем контрольную сумму и вставляем ее в начало файла
srec_cat part123.bin -bin -offset 0x04 -STM32_Big_Endian 0x00 -o part123_crc.bin -bin

Всем спасибо!

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


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

Решал аналогичную задачу.

Во-первых, CRC по алгоритму от ST - это -STM32_Little_Endian. Странно, что у Вас совпало. Переворачивали вручную, что-ли?..

 

А во-вторых, лучше прикрутить переворачивалку битов в нужное положение и использовать стандартный алгоритм CRC32.

 

 

/**
*  stm32tpl --  STM32 C++ Template Peripheral Library
*
*  Copyright © 2015 Anton B. Gusev aka AHTOXA
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  The above copyright notice and this permission notice shall be included in
*  all copies or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*
*
*  file         : stm32_crc.h
*  description  : STM32 Hardware CRC32 calculator
*
*/

#ifndef STM32TPL_STM32_CRC_H_INCLUDED
#define STM32TPL_STM32_CRC_H_INCLUDED

namespace STM32
{

class CrcCalculator
{
public:
CrcCalculator()
{
	RCC->AHBENR |= RCC_AHBENR_CRCEN;
	__DSB();
	CRC->CR = 1;
	__asm__ volatile ("nop");
	__asm__ volatile ("nop");
	__asm__ volatile ("nop");
}
~CrcCalculator() { RCC->AHBENR &= ~RCC_AHBENR_CRCEN; }
void Add(uint32_t w) { CRC->DR = w; }
uint32_t Result() { return CRC->DR; }

// вычисление по нестандартному алгоритму ST
// длина буфера указывается в uint32_t !
static uint32_t Calc(void const* buf, size_t len)
{
	CrcCalculator crc;
	uint32_t const * p = reinterpret_cast<uint32_t const *>(buf);
	for (size_t i = 0; i < len; ++i)
		crc.Add (p[i]);
	return crc.Result ();
}

// вычисление по стандартному алгоритму Ethernet/ZLib/...
// длина буфера указывается в uint32_t !
static uint32_t CalcStd (void const* buf, size_t len)
{
	CrcCalculator crc;
	uint32_t const * p = reinterpret_cast<uint32_t const *>(buf);
	for (size_t i = 0; i < len; ++i)
		crc.Add (__RBIT (p[i]));
	//crc.Add (__RBIT (crc.Result ()));
	return ~ __RBIT (crc.Result ());
}
};

} // namespace STM32

#endif // STM32TPL_STM32_CRC_H_INCLUDED

Это микро-библиотека подсчёта, автор - присутствующий тут AHTOXA (ещё раз спасибо!)

Я дописал CalcStd(), которая переворачивает байты, чтобы результат совпадал со стандартными реализациями.

 

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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