用于在引导加载程序应用程序中计算 crc 的软件逻辑
Software logic for calculating crc in a bootloader application
我找到了一个文件来通过一些接口检查传入应用程序的crc,程序如下:
#define CRC16POLY 0x1021
#define PKTLEN_128 128
typedef struct Crc16Data {
uint16_t currentCrc; //!< Current CRC value.
} crc16_data_t;
void crc16_init(crc16_data_t * crc16Config)
{
// initialize running crc and byte count
crc16Config->currentCrc = 0;
}
void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes)
{
uint32_t crc = crc16Config->currentCrc;
uint32_t j;
for (j=0; j < lengthInBytes; ++j)
{
uint32_t i;
uint32_t byte = src[j];
crc ^= byte << 8;
for (i = 0; i < 8; ++i)
{
uint32_t temp = crc << 1;
if (crc & 0x8000)
{
temp ^= 0x1021;
}
crc = temp;
}
}
crc16Config->currentCrc = crc;
}
void crc16_finalize(crc16_data_t * crc16Config, uint16_t * hash)
{
*hash = crc16Config->currentCrc;
}
我理解这是简单的 crc 软件逻辑,不涉及任何硬件生成的 crc 机制来计算传入应用程序的 crc,它只是计算应用程序的字节并将它们相加并正确放置?谁能解释 void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes)
函数内部发生了什么?
并且在其中一个文件中 crc16update(....)
函数被调用如下:
crc16_update(&crcInfo,buffer,PKTLEN_128);
在另一个函数 crcInfo
中,缓冲区信息来自
static void read_bytes(uint8_t * buffer, uint32_t byteCount)
{
uint32_t currentBytesRead = 0;
while(currentBytesRead != byteCount)
{
if (readOffset != writeOffset)
{
buffer[currentBytesRead++] = callback_buffer[readOffset++];
readOffset &= XMODEM_BUFLEN - 1;
}
}
}
static int read_packet(uint8_t *buffer, uint8_t idx)
{
uint8_t seq[2],crc1,crc2;
uint16_t crc16, verify16;
crc16_data_t crcInfo;
read_bytes(seq,2);
read_bytes(buffer,PKTLEN_128);
crc16_init(&crcInfo);
crc16_update(&crcInfo,buffer,PKTLEN_128);
crc16_finalize(&crcInfo,&verify16);
read_bytes(&crc1,1);
read_bytes(&crc2,1);
crc16 = ((uint16_t)crc1 << 8)|crc2;
if ((crc16 != verify16) || (seq[0] != idx) || (seq[1] != (uint8_t) ((~(uint32_t)idx)&0xff)))
return(-1);
return(0);
}
函数 void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes)
内部发生了什么?提前致谢。
此代码:
crc ^= byte << 8;
for (i = 0; i < 8; ++i)
{
uint32_t temp = crc << 1;
if (crc & 0x8000)
{
temp ^= 0x1021;
}
crc = temp;
}
用字节更新 CRC。它模拟运行一个线性反馈移位寄存器,其状态为crc
的值。这可以写得更紧凑,可能更容易看到发生了什么:
crc ^= byte << 8;
for (int i = 0; i < 8; i++)
crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
crc
的高位决定是否与寄存器异或多项式0x1021
,寄存器上移一位后,高位掉尾.
要了解有关如何实现此实现的更多信息,您应该阅读 Ross William's CRC tutorial。
我找到了一个文件来通过一些接口检查传入应用程序的crc,程序如下:
#define CRC16POLY 0x1021
#define PKTLEN_128 128
typedef struct Crc16Data {
uint16_t currentCrc; //!< Current CRC value.
} crc16_data_t;
void crc16_init(crc16_data_t * crc16Config)
{
// initialize running crc and byte count
crc16Config->currentCrc = 0;
}
void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes)
{
uint32_t crc = crc16Config->currentCrc;
uint32_t j;
for (j=0; j < lengthInBytes; ++j)
{
uint32_t i;
uint32_t byte = src[j];
crc ^= byte << 8;
for (i = 0; i < 8; ++i)
{
uint32_t temp = crc << 1;
if (crc & 0x8000)
{
temp ^= 0x1021;
}
crc = temp;
}
}
crc16Config->currentCrc = crc;
}
void crc16_finalize(crc16_data_t * crc16Config, uint16_t * hash)
{
*hash = crc16Config->currentCrc;
}
我理解这是简单的 crc 软件逻辑,不涉及任何硬件生成的 crc 机制来计算传入应用程序的 crc,它只是计算应用程序的字节并将它们相加并正确放置?谁能解释 void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes)
函数内部发生了什么?
并且在其中一个文件中 crc16update(....)
函数被调用如下:
crc16_update(&crcInfo,buffer,PKTLEN_128);
在另一个函数 crcInfo
中,缓冲区信息来自
static void read_bytes(uint8_t * buffer, uint32_t byteCount)
{
uint32_t currentBytesRead = 0;
while(currentBytesRead != byteCount)
{
if (readOffset != writeOffset)
{
buffer[currentBytesRead++] = callback_buffer[readOffset++];
readOffset &= XMODEM_BUFLEN - 1;
}
}
}
static int read_packet(uint8_t *buffer, uint8_t idx)
{
uint8_t seq[2],crc1,crc2;
uint16_t crc16, verify16;
crc16_data_t crcInfo;
read_bytes(seq,2);
read_bytes(buffer,PKTLEN_128);
crc16_init(&crcInfo);
crc16_update(&crcInfo,buffer,PKTLEN_128);
crc16_finalize(&crcInfo,&verify16);
read_bytes(&crc1,1);
read_bytes(&crc2,1);
crc16 = ((uint16_t)crc1 << 8)|crc2;
if ((crc16 != verify16) || (seq[0] != idx) || (seq[1] != (uint8_t) ((~(uint32_t)idx)&0xff)))
return(-1);
return(0);
}
函数 void crc16_update(crc16_data_t * crc16Config, const uint8_t * src, uint32_t lengthInBytes)
内部发生了什么?提前致谢。
此代码:
crc ^= byte << 8;
for (i = 0; i < 8; ++i)
{
uint32_t temp = crc << 1;
if (crc & 0x8000)
{
temp ^= 0x1021;
}
crc = temp;
}
用字节更新 CRC。它模拟运行一个线性反馈移位寄存器,其状态为crc
的值。这可以写得更紧凑,可能更容易看到发生了什么:
crc ^= byte << 8;
for (int i = 0; i < 8; i++)
crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
crc
的高位决定是否与寄存器异或多项式0x1021
,寄存器上移一位后,高位掉尾.
要了解有关如何实现此实现的更多信息,您应该阅读 Ross William's CRC tutorial。