MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/common/Crc.hpp

169 lines
5.3 KiB
C++
Raw Permalink Normal View History

2024-06-07 11:12:56 +03:00
/**
* @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_ */