MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/common/Crc.hpp
2024-06-07 11:12:56 +03:00

169 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file Crc.hpp
*
* @date Created on: 30 нояб. 2018 г.
* @author АО ДИАКОНТ
* - maksimenko
* @revision
* v1.0 - 6.12.2018
*/
#ifndef SOURCE_COMMON_CRC_HPP_
#define SOURCE_COMMON_CRC_HPP_
#include <cstddef>
#include <stdint.h>
namespace common {
namespace crc {
/**
* @brief Менеджер таблицы расчета контрольной суммы
* @param Param тип описывающий алгоритм подсчета (см. CrcDesc.hpp)
* @detailed Ведет подсчет ссылок на объекты хранения контрольной суммы для
* обеспечивая выденленным на куче таблицей расчета CRC. Удаляем таблицу
* при уничтожении всех объекты хранения контрольной суммы.
*/
template <typename Param>
class CrcTable {
typedef typename Param::res_t res_t;
res_t * mCrcTbl;
uint16_t mcRef;
public:
static CrcTable & Instance();
res_t operator[](int i) { return mCrcTbl[i]; }
CrcTable & operator++() { mcRef++; if ( !mCrcTbl )alloc (); return *this; }
CrcTable & operator--() { if ( !--mcRef )free (); return *this; }
void inititialize() {
alloc();
}
private:
CrcTable() : mCrcTbl(NULL), mcRef(1) {}
CrcTable(const CrcTable &);
CrcTable & operator=(const CrcTable &);
void alloc() {
static res_t crc_table[256];
mCrcTbl = crc_table;
for ( uint32_t i = 0; i < 256; i++ ) {
uint32_t v = Param::reflect ? i: i << (Param::width_bit-8);
for ( uint16_t j = 0; j < 8; j++ ) {
v = Param::reflect ?
v & (1UL<<(0 )) ? (v>>1) ^ Param::poly : (v>>1) :
v & (1UL<<(Param::width_bit-1)) ? (v<<1) ^ Param::poly : (v<<1);
}
mCrcTbl[i] = v & ~0UL>>(32-Param::width_bit);
}
}
void free() {
//mCrcTbl = NULL;
}
};
template <typename Param>
CrcTable<Param>& CrcTable<Param>::Instance() {
static CrcTable mObj;
return mObj;
}
/**
* @brief Хранилище значения контрольной суммы
* @detailed Взаимодействует c CrcTable<Param> обеспечивая доступ к таблице
* для расчета CRC. Обеспечивает начальный и конечный этап получения
* контрольной суммы. Реализует операторы приведения типа возвращающий
* конечную стадию (XOR) вычисления CRC.
*/
template <typename Param>
class CrcVal {
typedef typename Param::res_t res_t;
res_t mCrc;
public:
CrcTable<Param> & mCrcTbl;
public:
CrcVal () : mCrc(Param::init), mCrcTbl(CrcTable<Param>::Instance()) {
++mCrcTbl;
}
CrcVal & operator=(const CrcVal & obj) {
mCrc = obj.mCrc;
return *this;
}
CrcVal( const CrcVal & obj ) : mCrcTbl(CrcTable<Param>::Instance()) {
mCrc = obj.mCrc;
++mCrcTbl;
}
operator uint32_t() const {
return mCrc & ~0UL>>(32-Param::width_bit) ^ Param::final;
}
operator uint16_t () const {
return (uint32_t)mCrc;
}
#ifdef __GNUG__
operator uint8_t () const { return (uint32_t)mCrc; }
#endif
res_t & value() const {
return const_cast<res_t &>(mCrc);
}
res_t & value() {
return mCrc;
}
~CrcVal () {
--mCrcTbl;
}
};
/**
* @brief Подсчет контрольной суммы блока данных
* @param Param тип описывающий алгоритм подсчета (см. CrcDesc.hpp)
* @param pData указатель на блок данных
* @param nBytes размер блока данных в байтах (октеты)
* @param crcOld объект хранения текущего значения контрольной суммы
* @retval Обновленный объект хранения значения контрольной суммы
* @detailed Возможны два типа запуска: с параметром по умолчанию - создаем
* новое инициализированное хранилище на выходе (начало расчета),
* используем существующее хранилище - добавление результата расчета
* очередного блока данных.
*/
template <typename Param>
typename Param::crc_t crcCalc( const char * pData, uint32_t nBytes,
const typename Param::crc_t & crcOld = typename Param::crc_t() ) {
typename Param::res_t & crc = crcOld.value();
uint16_t data, octet = 0; (void)octet;
while ( nBytes-- ) {
#ifdef __TMS320C2000__
data = __byte( (int*)pData, octet );// nSize -= octet;
octet ^= 1; pData += !octet;// Адрес следующего слова данных
#endif
#ifdef __GNUG__
data = *pData++;
#endif
data &= 0xFF;
crc = Param::reflect ?
crcOld.mCrcTbl[data^(crc & 0xFF)] ^ (crc >> 8):
crcOld.mCrcTbl[data^(crc >> (Param::width_bit-8) & 0xFF)] ^ (crc << 8);
}
return crcOld;
}
} // namespace crc
} // namespace common
#include "CrcDesc.hpp"
#endif /* SOURCE_COMMON_CRC_HPP_ */