FCE加速计算CRC

1. 运行时间

FUNC(void, MemTst_CODE) MemTst_Cyclic1000ms(void) /* PRQA S 0624, 3206 */ /* MD_Rte_0624, MD_Rte_3206 */
{
  uint32 t1;
  uint32 t2; 

#if MEMTST_COMPLIE_COMMAND
  t1 = REALTIME_STM_IN_US;
  FlsTst_Check_Sum();
  t2 = REALTIME_STM_IN_US;
  memt_data.times[i] = t2 - t1;
#endif
  FlsTst_TxManager();
  i += 1;
}

对执行FCE引擎加速的函数FlsTst_Check_Sum()进行计算时间测试。经过多次测试,得出平均计算时间为126777微秒,0.12s。最大、最小值上下浮动不超过1000微秒。传统的通过CRC TABLE方式计算的时间为700645微秒,0.7s,提升计算速度70%

2. 底层原理与优势

FCE(Flexible CRC Engine)是专用于微控制器中用于硬件CRC计算的模块。相比于软件实现,FCE通过硬件加速器计算CRC,极大提高了计算效率。具体来讲,硬件实现通常包括一个 移位寄存器 和一个 反馈多项式,它们协同工作来处理输入数据并生成 CRC 值。此外,**FCE利用DMA(直接内存访问)来搬运数据,用户输入数据后,DMA驱动会使用专为CRC计算的DMA通道传输数据(EB Treos配置)。这个过程无需CPU的参与,数据流完全由DMA接管,大大减小了CPU资源的占用。DMA传输是硬件执行,所以在传输完成后会自动触发DMA中断(Dma_ChInterruptHandler)。需要注意的是,要在达芬奇中配置对应DMA通道的中断,且优先级不能在所有DMA传输通道中最低,否则无法调用中断函数,进而无法通过用户自定义的回调函数来返回CRC结果。

由于使用DMA控制器管理数据,CPU不再需要逐字节加载数据,从而释放出大量的处理资源,CPU可以专注于其他任务。此外,DMA能够快速搬移大块数据,避免了CPU数据加载和处理的瓶颈,大幅度提高了传输速度。综上,FCE结合DMA的CRC计算可以减小CPU资源消耗、减小传输延迟、提高传输速度。

3. 实施细节与DTC置出

根据*MC-ISAR_TC3xx_UM_Dma.pdf,MC-ISAR_TC3xx_UM_Crc.pdf,*的等Infenion提供的文档进行EB Treos中Crc, DMA模块配置。在达芬奇中进行自己定义的DMA通道的中断函数,同时修改该中断函数优先级(增加),需要在UDE调试工具中查看**Dma_ChInterruptHandler是否被调用。**且如果Crc.c中没有Crc_DmaCalculateCRC32,即DMA相关函数,在Infenioin中将相关函数Copy到Vector公司当下Crc.c模块下。

由于DMA每次只能搬运16K的数据,且数据需要4byte对齐所以在数据传输时需要将数据分块传输,且需要等待DMA中断触发后进行下一次分块的传输,建议代码中加入以下代码等待DMA Channel 释放,否则只能将第一块数据搬运,后续搬运会显示CRC_BUSY。导致计算CRC结果不完整,置出ROM ERROR DTC。

        while (!memt_data.is_transfer_complete)
        {
          memt_data.DEvent = Dma_GetEvents(13U);
        }
      if (memt_data.is_first_run_checksum == TRUE)
      {
        len = APP_APPLICATION_END_ADDR - APP_APPLICATION_START_ADDR + 1uL;
        /* Partition calculation to adapt to the maximum transfer byte 
        of DMA (CRC_DMA_MAXLENGTH) */
        memt_data.remaining_length = len;
        memt_data.crc_result = MEMT_CRC_START_VAL;
        memt_data.is_first_run_checksum = TRUE;
        memt_data.current_address = (uint8 *)APP_APPLICATION_START_ADDR;
      }
      while (memt_data.remaining_length > 0)
      {
        memt_data.chunk_size = (memt_data.remaining_length > 
													        CRC_DMA_MAXLENGTH_ALIGNED)
                                   ? CRC_DMA_MAXLENGTH_ALIGNED
                                   : ((memt_data.remaining_length / 4) * 4);
        memt_data.test_flag = Crc_DmaCalculateCRC32(memt_data.current_address,
         memt_data.chunk_size, memt_data.crc_result, memt_data.is_first_crc_result);
        while (!memt_data.is_transfer_complete)
        {
          memt_data.DEvent = Dma_GetEvents(13U);
        }
        memt_data.crc_result = memt_data.app_checksum_value; // KEY change:onlyyyy...
        memt_data.remaining_length -= memt_data.chunk_size;
        memt_data.current_address += memt_data.chunk_size;
        memt_data.is_first_crc_result = FALSE;
        memt_data.is_transfer_complete = FALSE; /* Only open when triggering ISR interrupt. */

由于分块传输,所以将要计算的APP起始地址、每次传输的块以及剩余APP长度设置为全局变量。等待While循环结束后进行大小端转换。

需要注意,Crc_DmaCalculateCRC32是不直接返回CRC Value的,它是由DMA 中断函数在数据传输完成后调用的回调函数来返回的,这个函数用户自己定义即可,如下图所示。

/* This function will call automaticly by pointer. 
Called by [Crc_DmaTransferIsr] defined in Crc.c. */
void Mem_CrcNofitCore0(uint32 res)
{
    memt_data.is_transfer_complete = TRUE;
    // is_call_times += 1;
    memt_data.app_checksum_value = res;
    return res;
};

DTC置出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上位机刷写app.hex无ROM Error DTC

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ROM Error DTC置出—-修改hexview checksum值

4. 其他

优先级配置

Os_Hal_Cat1InterruptEntry(0, 76, ISR_DMACH12SR)
Os_Hal_Cat1InterruptEntry(0, 68, ISR_DMACH13SR)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值