STM32 硬件CRC和软件CRC速度比较

一、测试条件

硬件: STM32L432KC
主频: 80MHz
编译器: IAR 8.20.1
编译选项: High Speed no size constraints
CRC 生成多项式: 0x782f

二、测试方法

软件提前生成CRC表,用于查询。分别使用软件CRC算法和硬件CRC外设对一个缓存进行计算,目的是从该缓存中找到同步头。同步头共11字节,前两个字节为后九个字节的CRC校验值。通过迭代算法依次对11字节进行计算和比较,当找到同步头后返回同步头偏移量。通过时间比较两者之间的速度。

三、测试结果

迭代24464次后,从缓存中找到同步头。
不开启编译时间优化时,软件算法用时238ms,硬件CRC用时220ms。
这里写图片描述

开启编译时间优化后,软件算法用时159ms,硬件CRC用时186ms。
这里写图片描述

四、附测试代码

#include "user_crc.h"
#include "stm32l4xx_hal.h"

#define SOFT_CRC  1
#define HARD_CRC  2

CRC_HandleTypeDef   CrcHandle;
uint16_t crc_tab[256];

void crc_init()
{
    /*##-1- Configure the CRC peripheral #######################################*/
    CrcHandle.Instance = CRC;

    /* The default polynomial is not used. It is required to defined it in CrcHandle.Init.GeneratingPolynomial*/    
    CrcHandle.Init.DefaultPolynomialUse      = DEFAULT_POLYNOMIAL_DISABLE;

    /* Set the value of the polynomial */
    CrcHandle.Init.GeneratingPolynomial      = CRC_POLYNOMIAL_16B;

    /* The user-defined generating polynomial generates a
         16-bit long CRC */
    CrcHandle.Init.CRCLength                 = CRC_POLYLENGTH_16B;

    /* The default init value is used */
    CrcHandle.Init.DefaultInitValueUse       = DEFAULT_INIT_VALUE_DISABLE;

    /* The input data are not inverted */
    CrcHandle.Init.InputDataInversionMode    = CRC_INPUTDATA_INVERSION_NONE;

    /* The output data are not inverted */
    CrcHandle.Init.OutputDataInversionMode   = CRC_OUTPUTDATA_INVERSION_DISABLE;

    /* The input data are 8-bit long */
    CrcHandle.InputDataFormat                = CRC_INPUTDATA_FORMAT_BYTES;

    if (HAL_CRC_Init(&CrcHandle) != HAL_OK)
    {
        /* Initialization Error */
        Error_Handler();
    }
}

void crc_buildTab(uint16_t gen_polynom)
{
    for(int value = 0; value < 256; value++) 
    {
        uint16_t crc = value << 8;

        for(int i = 0; i < 8; i++) 
        {
            if(crc & 0x8000)
                crc = (crc << 1) ^ gen_polynom;
            else
                crc = crc << 1;
        }

        crc_tab[value] = crc;
    }

}

uint16_t soft_crc_calc(const uint8_t *data, uint16_t len) 
{
    uint16_t crc = 0x0000;

    for(uint16_t offset = 0; offset < len; offset++)
    {
        crc = (crc << 8) ^ crc_tab[(crc >> 8) ^ data[offset]];
    }

    return crc;
}

uint16_t hard_crc_calc(const uint8_t *data, uint16_t len)
{
    uint16_t crc = 0x0000;

    crc = HAL_CRC_Calculate(&CrcHandle, (uint32_t *)data, len);

    return crc;
}

uint16_t find_sync_word(uint8_t *data, uint32_t data_len, uint8_t crc_type)
{
    uint8_t *ptr;
    uint16_t crc_stored,crc_calced;

    ptr = data;

    for(uint32_t i=0; i<data_len-9; i++)
    {
        crc_stored = ptr[0]<<8 | ptr[1];
        if(crc_type == SOFT_CRC)
        {
            crc_calced = soft_crc_calc((uint8_t *)&ptr[2], 9);
        }
        else if(crc_type == HARD_CRC)
        {
            crc_calced = hard_crc_calc((uint8_t *)&ptr[2], 9);
        }

        if( (crc_stored != 0x0000) && (crc_stored == crc_calced) )
        {
            printf("crc check ok! crc1 = 0x%04x,crc2 = 0x%04x\n", crc_stored,crc_calced);
            return i;
        }

        ptr++;
    }

    return 0xffff;
}


void crc_test()
{
    uint32_t tick1,tick2;
    uint32_t find_cnt = 0;
    uint16_t gen_polynom = 0x782f;

    crc_init();
    crc_buildTab(gen_polynom);

    tick1 = HAL_GetTick();
    find_cnt = find_sync_word((uint8_t *)superFrameBuf, sizeof(superFrameBuf), SOFT_CRC);
    tick2 = HAL_GetTick();
    printf("use soft_crc find sync word after %d iteration, use time %d\n", find_cnt, tick2 - tick1);

    printf("\n");

    tick1 = HAL_GetTick();
    find_cnt = find_sync_word((uint8_t *)superFrameBuf, sizeof(superFrameBuf), HARD_CRC);
    tick2 = HAL_GetTick();
    printf("use hard_crc find sync word after %d iteration, use time %d\n", find_cnt, tick2 - tick1);

}
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 通用的CRC32校验程序可以用于检验数据的完整性,它可以完美匹配STM32硬件CRC算法。 CRC32是一种循环冗余校验算法,它使用32位的多项式来生成校验值。通用的CRC32校验程序可以按照CRC32算法进行计算,以确保数据的准确性。 在STM32芯片中的硬件CRC算法也是基于CRC32标准的,但它是通过硬件指令进行加速计算的。使用通用的CRC32校验程序可以实现与STM32硬件CRC算法相同的计算结果。 使用通用的CRC32校验程序,首先需要确定待校验数据的多项式以及初始值。以CRC32标准为例,多项式为0x04C11DB7,初始值为0xFFFFFFFF。 接下来,将待校验的数据逐位进行异或和移位操作,并与多项式进行多次异或操作,直到数据处理完毕。最后,取最终的校验值进行比较。 通用的CRC32校验程序与STM32硬件CRC算法相比,虽然执行效率会稍低一些,但其结果可以完全匹配。因此,在没有硬件CRC加速指令可用的情况下,使用通用的CRC32校验程序可以有效地实现数据的校验。 总之,通用的CRC32校验程序能够完美匹配STM32硬件CRC算法,通过按照CRC32标准进行计算,并与多项式和初始值进行异或和移位操作,最终得到校验值。虽然执行效率稍低,但可以保证数据的完整性。 ### 回答2: 通用CRC32校验程序是一种用于数据校验的算法,可以完美匹配STM32硬件CRC算法。CRC32(Cyclic Redundancy Check)是一种循环冗余校验算法,用于检测和校验数据传输中的错误。 通用CRC32校验程序的实现方式如下: 1. 创建一个CRC32表,用于加快CRC计算的速度。这个表的大小为256个32位无符号整数。 2. 初始化CRC寄存器的值为0xFFFFFFFF。 3. 对待校验的数据进行逐字节的计算。 4. 将当前CRC寄存器的值与当前数据字节进行异或运算。 5. 取CRC寄存器当前值的低8位,作为索引查表,得到一个新的32位无符号整数。 6. 将CRC寄存器的值右移8位。 7. 将查表得到的32位无符号整数与CRC寄存器的值进行异或运算。 8. 重复步骤5到步骤7,直到处理完所有的数据字节。 9. 对最终得到的CRC寄存器的值进行取反操作,得到最终的CRC32校验值。 通用CRC32校验程序能够完美匹配STM32硬件CRC算法的原因是它采用了相同的计算方法和相同的CRC32表。因此,通过使用这个通用的校验程序可以在软件层面上实现与STM32硬件CRC算法相同的校验结果,从而保证数据传输的可靠性。 ### 回答3: 通用的CRC32校验程序可以完美匹配STM32硬件CRC算法。CRC32(循环冗余校验)是一种常用的数据校验方法,能够有效检测数据传输或存储中的错误。STM32是一系列32位微控制器,其中的硬件CRC模块可以直接进行CRC32计算,使得校验过程更加高效。 通用的CRC32校验程序基本思路是利用位移和异或操作,在数据上逐位计算并更新CRC校验值。为了完美匹配STM32硬件CRC算法,首先需要确定CRC的生成多项式和初始值。在STM32中,多项式是0x04C11DB7,初始值是0xFFFFFFFF。 在编写通用的CRC32校验程序时,我们可以先定义一个数组,包含了从0到255的所有可能的8位二进制数。然后,通过一个循环,将每个字节与CRC校验值进行异或操作,并根据某种规则进行位移处理。最后,返回CRC校验值即可。 为了与STM32硬件CRC算法完美匹配,我们需要在校验前对输入数据进行字节反转操作,以保证数据的高字节在前,低字节在后。这是因为STM32硬件CRC模块对输入数据是按字节反转的。 总的来说,通用的CRC32校验程序可以与STM32硬件CRC算法完美匹配,但在使用时需要注意数据的字节顺序。这样,我们就可以使用通用的CRC32校验程序来进行数据的校验,而无需依赖STM32硬件CRC模块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值