聊聊嵌入式系统中常用的循环冗余校验技术

发布者:RainbowDreamer最新更新时间:2025-02-10 来源: jianshu关键字:嵌入式系统 手机看文章 扫描二维码
随时随地手机看文章

所谓完整性是指数据在其生命周期中的准确性和一致性。这些数据可能存储在EEPROM/FLASH里,或者基于通信协议进行传输,它们有可能因为外界干扰或者程序错误,甚至系统入侵而导致被破坏。如果这些数据在使用前不做校验,产品功能可能失效。在一些特定领域,严重时可能会危及用户财产甚至生命安全。


本文就来聊聊使用较为广泛的循环冗余校验技术,以及在STM32中的一些具体使用体会。

所谓循环冗余校验(CRC:Cyclic Redundancy Check)是一种错误检测算法,通常在通信协议中或存储设备中用于检测原始数据的意外变动。可以简单理解成对有用数据按照一定的算法进行计算后,提取出一个特征值,并附加在有用数据后。在应用中将有用数据按照特定的算法提取特征值与预先存储的特征值进行比对,如相等则校验通过,反之校验失败,从而识别出数据是否异常。


为何要校验数据完整性(Data Integrity)?

数据在存储以及传输的过程中可能发生异动。以数据通信应用场景为例,常见的错误大致有两种失效模式:

单个位错误(Single Bit Error):仅仅某一个数据位出现错误,如图:

突发错误(BurstError):两个或更多个数据位在码流中出现错误,如图:

为什么可能会出现这些位错误呢?对于电子系统通信,它涉及到物理层、链路层、通信介质等,其中物理层主要将原始二进制数据利用一定的编解码原理对其进行调制,然后经由发送电路将调制信号输送至传输介质,接收端利用接收电路进行接收并解调,将信息还原成二进制码流。在这个过程中介质有可能被干扰,接收电路、发送电路、调制电路、解调电路都可能由于某些干扰原因导致工作失效而出现误码。此时,如果没有一个很好的机制去确保数据的正确性,比如一个飞控系统中某些控制命令、车辆系统中CAN报文数据,系统直接使用这些错误数据去控制被控对象(比如电机、发动机等),严重的时候就会造成难以估量的生命财产灾难。

存储系统中的数据也是一样。一般来说,系统在上电运行时会从物理存储介质装载系统参数,比如一些校准数据。如果由于介质的某些位被破坏,或者软件bug导致数据被误操作了,而没有数据完整性检测,这样的数据直接被应用于系统控制,一样会造成安全隐患。

所以,对于数据完整性检测的重要性不言而喻。常见的数据完整性算法有很多种,比如简单的异或校验、CRC循环冗余校验、FEC前向纠错算法等等。而循环冗余校验在嵌入式系统中应用非常广泛,在通信协议制定、数据存储、压缩解压算法等都有广泛的应用。

循环冗余校验使用二进制除法作为算法原理,具有强大的错误检测机制。对于二进制除法使用少量的硬件逻辑电路就可实现。至于软件代码实现,有查表法和移位计算两种思路及策略。查表法以空间换时间,移位计算法以时间换空间。

何为循环冗余校验?

循环冗余校验的核心数学算法原理基于循环码,在不增加原始数据的信息基础上扩展了信息,以极小的存储代价存储其冗余特征。该算法是W. Wesley Peterson 于1961年发明的。

这里的n位二进制数据为有效信息载荷。(可能是传输或存储的有用信息)

根据CRC算法计算出m位冗余码,即根据该CRC校验多项式结合CRC算法从前面有效数据中提取出特征冗余码,这就是冗余的真实含义。

实际传输或者存储的就是n+m位二进制数据。

这里引出一个概念:多项式,在CRC校验算法中多项式可做如下理解及表示:

其本质就是多进制的数学表示法,这里是二进制,故X为2。

其基本的算法处理过程示意如下:

假定待发送有效数据为二进制多项式M(x),而校验多项式P(x)为收发双方约定好了的,双方已知,这里介绍一下几个多项式表示的意思及相关处理流程:

接收方接收到数据后进行CRC校验。余数为0,校验通过。

其实CRC的本质就是二进制多项式除法求取冗余码的计算过程,无论软件的查表法、移位计算法,还是纯硬件逻辑电路实现,本质都是一样的。对于数字逻辑电路利用移位计算则更具优势,因为几乎不占用CPU时间。

常见的CRC校验多项式

常见的CRC校验多项式算子有哪些?

不同的校验多项式,除了复杂度有差异外,从应用角度看有什么差异呢?从应用角度看主要体现在错误诊断率。不妨看看CRC-16以及CRC-CCITT的错误检测效果:

可完全检测出单bit及双bit错误

奇数个位错误

能检测出16位长度及小于16的突发错误

能以99.997%的概率检测出长度为17位及以上的错误

选择不同的校验多项式算子,其位错误诊断成功率是不一样的,当然其计算开销也不一样。我们来查查权威的IEC标准看看。下图截自《IEC61508-7》。

由上文可见,CRC-8可诊断出99.6%的位错误概率,而CRC-16则提高至99.998%的位错误概率。

注:IEC61508是国际电工委员会功能安全标准(Functional safety of electrical/electronic/programmable electronicsafety-related systems)。

技术发展至今,已有大量不同的校验多项式生成器被各行各业使用。下面是来自wikipedia截图,供大家参考:

STM32的CRC硬件外设

如下图,STM32内置了一个CRC-32硬件计算单元,实现了一个固定多项式0x4C11DB7(16进制表示),可应用于以太网报文校验码计算。

STM32 全系列产品都具有 CRC 外设,对 CRC 的计算提供硬件支持,节省了应用代码存储空间。CRC 校验值既可以用于传输中的数据正确性验证,也可用于数据存储时的完整性检查。在 IEC60335 中,也接受通过 CRC 校验对 FLASH 的完整性进行检查。在对 FLASH 完整性检查的应用中,需要事先计算出整个 FLASH 的 CRC 校验值(不包括最后保存CRC 值的字节),放在FLASH 的末尾。在程序启动或者运行的过程中重新用同样的方法计算整个 FLASH 的 CRC 校验值,然后与保存在 FLASH 末尾地址空间的 CRC 值进行比较。

EWARM 从 v5.5 版本之后开始支持 STM32 芯片的 CRC计算。计算整个 FLASH的 CRC 校验值并保存在 FLASH末尾的过程,可以在 IAR 中完成。通过配置EWARM 的 CRC 计算参数,自动对整个 FLASH 空间进行 CRC 计算,并将计算结果放到 内部FLASH空间 的末尾。

或许你会问,这有什么应用价值呢?不妨以基于MCU程序的升级为例。在代码升级过程中,如果不对bootloader升级接口传入的二进制程序文件做校验,就无法及时发现升级过程中发生的代码错误。相反,如果原始代码添加了校验码,升级程序在接受到升级文件后做校验计算,并与待升级文件末尾的校验码进行比对,如果不匹配则放弃升级,这样就不至于将无效的甚至有安全隐患的代码写进芯片。

修改 Link 文件,指定 checksum 在FLASH 中的存储位置,在 Link 文件中增加下面语句。

place at end of ROM_region { ro section .checksum };    

该语句指定将 CRC 的值放在 FLASH 空间的末尾位置。是整个 FLASH 空间的末尾,不是应用程序的代码末尾。这样,CRC 值的位置就是固定的,不会随代码大小而变化。 

配置 Checksum 页面的参数

IAR Checksum 页说明(v6.4 及以上)

IAR 的 checksum 页面分为两个部分:

红线圈出的部分:定义了FLASH 中需要计算 CRC 的范围和空闲字节填充值。

checksum 计算参数的设定部分:Checksum size:选择 checksum 的大小(字节数)

Alignment:指定 checksum 的对齐方式。不填的话默认 2 字节对齐。

Algorithm:选择 checksum 的算法

Complement:是否需要进行补码计算。选择“As is”就是不进行补码计算。

Bit order:位输出的顺序。MSB first,每个字节的高位在前。LSB first,每个字节的低位在前。

Reverse byte order within word:对于输入数据,在一个字内反转各个字节的顺序。

Initial value:checksum 计算的初始化值 

Checksum unit size :选择进行迭代的单元大小,按 8-bit,16-bit 还是 32-bit 进行迭代。

STM32 CRC 外设使用默认配置时 IAR 的配置

STM32CRC 外设的配置:

POLY= 0x4C11DB7(CRC32) 

Initial_Crc = 0Xffffffff 

输入/输出数据不反转 

输入数据:0x08000000~0x0801FFFB。(最后 4 个字节用来放计算出的 CRC 值)

在实验的过程发现, ”Alignment ”似乎对计算出的 CRC 值没有影响。但“Reverse byte order within word ”与“Checksumunit size ”这两项的配置有一定关系。如果后者选择 32-bit,则不能勾选前者;反之如果后者选择 8-bit,则一定要勾选上“ Reverse byte order within word ”。也可以参照下图进行设置:

对于IAR v6.4 以下版本,没有”Checksum unit size”选项。参考配置如下:

代码怎么写?

如前文描述,这个应用可以用于对Flash中数据进行校验,参考代码如下:

/*-1- 配置CRC外设 */  CrcHandle.Instance = CRC;  /* 默认二进制多项式使能 */  CrcHandle.Init.DefaultPolynomialUse    = DEFAULT_POLYNOMIAL_ENABLE;  /* 默认初值设置 */  CrcHandle.Init.DefaultInitValueUse     = DEFAULT_INIT_VALUE_ENABLE;  /* 输入数据不反转 */  CrcHandle.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_NONE; /* 输出数据不反转 */  CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLED;  /* 输入数据基本单元长度为32bit */  CrcHandle.InputDataFormat              = CRC_INPUTDATA_FORMAT_WORDS;  if(HAL_CRC_Init(&CrcHandle) != HAL_OK)  { /* 初始化错误 */    Error_Handler();   }  pdata = (uint32_t*)ROM_START; /*##-2- 调用HAL库利用硬件CRC外设对ROM区计算CRC-32校验码*/  uwCRCValue = HAL_CRC_Calculate(&CrcHandle, pdata, ROM_SIZEinWORDS);

小结

对于CRC应用,还可以根据多项式算子编写纯软件方案,网上有很多现成的代码。其基本思路无外乎查表法以及移位计算法。差异在于一个牺牲存储空间以换取计算效率,一个牺牲计算时间而节省存储空间,至于如何选择,则根据所设计的系统综合考虑,一般根据应用场景来定。

将块数据利用CRC算法计算出冗余码,有的文章、标准称这个冗余码为签名。实际应用时计算有效数据所得校验码与预存校验码进行比较,相等则校验通过,反之则失败。当然,也可以将原数据与所存校验码一起传入校验算法,所得结果为0则校验通过,反之失败。

对于数据通信,一般会在报文的尾部添加有效数据的校验码,再由接收方校验收到报文的数据完整性


关键字:嵌入式系统 引用地址:聊聊嵌入式系统中常用的循环冗余校验技术

上一篇:STM32F103学习笔记(8)——读取芯片UID和MAC地址
下一篇:DJI RM A board study —— 点亮LED灯

推荐阅读最新更新时间:2026-03-21 23:29

ARM和DSP芯片的双核嵌入式系统的总体设计
嵌入式系统的核心是嵌入式微处理器和嵌入式操作系统。早期的嵌入式系统硬件核心是各种类型的8位和16位单片机;而近年来32位处理器以其高性能、低价格,得到了广泛的应用。近年来,又出现了另一类数据密集处理型芯片DSP。DSP由于其特殊的结构、专门的硬件乘法器和特殊的指令,使其能快速地实现各种数字信号处理及满足各种高实时性要求。随着现代嵌入式系统的复杂度越来越高,操作系统已成为嵌入式系统不可缺少的部分。免费的嵌入式操作系统,如 Linux等,随着自身不断的改善,得到了飞速的发展。Linux是一个免费的、强大的、可信赖的、具有可伸缩性与扩充性的操作系统。Linux实现了许多现代化操作系统的理论,并且支持完整的硬件驱动程序、网络通信协议与多处
[单片机]
ARM和DSP芯片的双核<font color='red'>嵌入式系统</font>的总体设计
MCU AI/ML - 弥合智能和嵌入式系统之间的差距
人工智能(AI)和机器学习(ML)是使系统能够从数据中学习、进行推理并随着时间的推移提高性能的关键技术。 这些技术通常用于大型数据中心和功能强大的GPU,但在微控制器(MCU)等资源受限的器件上部署这些技术的需求也在不断增加。 本文将探讨MCU技术和AI/ML的交集,以及它如何影响低功耗边缘设备。同时将讨论在电池供电设备的MCU上运行人工智能的困难、创新和实际应用场景。 AI/ML和MCU:简要概述 人工智能创建的计算机系统可以执行类似人类的任务,例如理解语言、寻找模式和做出决定。机器学习是人工智能的一个子集,涉及使用算法让计算机从数据中学习并随着时间的推移不断改进。机器学习模型可以寻找模式、排序对象、并从示例中预测结
[嵌入式]
一种利用实时时钟降低嵌入式系统功耗的方法
  1.嵌入式CPU低功耗模式介绍   众所周知,低功耗已经是衡量一个嵌入式系统的重要指标。而作为嵌入式系统的核心,嵌入式CPU的功耗则对整个系统起着重要的作用。当前流行的嵌入式系统CPU,基本都提供低功耗特性。一般而言,当嵌入式CPU都会有工作模式与低功耗模式,而低功耗模式又可进一步分为空闲模式,休眠模式,睡眠模式等。进入低功耗模式后,CPU的功耗会降低很多。而外部中断发生时,可以将CPU唤醒。一个嵌入式系统运行起来后,当系统进入idle状态时,就可以让CPU进入低功耗模式,而当外部中断发生时,再唤醒CPU,重新回到工作模式。让CPU尽可能多的处于低功耗模式,可以大大降低系统的功耗。然而,即使系统处于idle而且没有别的工作要做
[单片机]
一种利用实时时钟降低<font color='red'>嵌入式系统</font>功耗的方法
利用与硬件无关的方法简化嵌入式系统设计:驱动程序实现
摘要 本文探讨如何在项目中实现与硬件无关的驱动程序。即插即用的设计理念能够显著降低嵌入式软件或固件设计的复杂性,无论设计者的经验水平如何,都能从中受益。如果您想了解驱动程序的基本函数和嵌入式系统的软件架构,请参见文章“利用与硬件无关的方法简化嵌入式系统设计:基本知识”。 简介 在嵌入式系统设计中,设计人员通常要编写驱动程序和固件的代码,确保所选传感器能够实现其所需的基本功能。这一过程往往耗时且繁琐。为解决这一难题,可以通过结合硬件、软件和固件的方式,采用即插即用的设计思路,从而简化传感器的选择和系统集成。与硬件无关的驱动程序不仅能够让传感器集成变得更加高效,还可以作为一种通用解决方案,便于在未来的设计中重复使用。
[嵌入式]
利用与硬件无关的方法简化<font color='red'>嵌入式系统</font>设计:驱动程序实现
利用与硬件无关的方法简化嵌入式系统设计:基本知识
摘要 本文将演示一种加速嵌入式系统设计原型阶段的方法,说明如何将与硬件无关的驱动程序和传感器结合使用,简化整个嵌入式系统的器件选择。同时还将介绍嵌入式系统的器件、典型软件结构以及驱动程序的实现。后续文章“利用与硬件无关的方法简化嵌入式系统设计:驱动程序实现”将进一步探讨执行过程。 简介 通过使用与硬件无关的驱动程序,设计人员可以自由选择微控制器或处理器的类型来管理传感器,而不受硬件的限制。这种方法的优势在于,除了供应商提供的基本软件层外,还可以添加额外的软件层,同时简化传感器的集成。本文将以惯性测量单元(IMU)传感器为例,说明如何实现与硬件无关的驱动程序,不过,这种方法同样适用于其他类型的传感器和器件。驱动程
[嵌入式]
利用与硬件无关的方法简化<font color='red'>嵌入式系统</font>设计:基本知识
基于s5pv210嵌入式系统busybox文件系统移植
1、下载源码 busybox.net/downloads下载最新版的busybox源码,最新源码为1.21.1 2、解压源码文件 tar xvf busybox-1.21.1.tar.bz2 3、进入busybox cd busybox-1.21.1 4、阅读README文件,查看编译步骤 重点阅读上面一段 5、配置源码 make menuconfig 修改编译工具为交叉编译工具 Busybox Settings --- Build Options--- Cross Compiler prefix为你机器里交叉编译工具链的前缀,我的名字叫arm-none-linux-gnueabi-gcc所以填写arm-none-li
[单片机]
基于s5pv210<font color='red'>嵌入式系统</font>busybox文件系统移植
嵌入式系统调试仿真工具
嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新型号的不断涌现和不断更新,目前市面上的嵌入式系统调试仿真工具也层出不穷,这些调试仿真工具因其功能、性能、通用性的不同价格也相差非常悬殊,从几十元的简易JTAG调试器到几万元甚至几十万元的高端调试仿真器应有尽有,以前这方面的工具大部分都是进口的,现在国内有些公司也开始开发这方面的工具,而且性价比很好,只是国内做的大部分都是专用的,通用的比较少,因为通用的应用也很少,而且价格昂贵。 下面列举一些我曾经用过的调试仿真工具: 1)MCS-51单片机调试仿真系统MDS-55-B5,由三环电子
[单片机]
AMD 面向嵌入式系统推出高能效 EPYC 嵌入式 8004 系列
AMD 凭借其 EPYC™ 嵌入式处理器不断树立行业标准,为网络、存储和工业应用提供卓越的性能、效率、连接与创新。今天,我们正以 第四代 AMD EPYC 嵌入式 8004 系列 处理器扩展这一领先地位。 AMD EPYC 嵌入式 8004 系列处理器专为计算密集型嵌入式系统所设计,可为高需求工作负载提供卓越性能,同时以紧凑的尺寸规格最大限度为空间和功率受限型应用提升能效。它还集成了一整套嵌入式功能,以进一步强化系统性能与可靠性。AMD EPYC 嵌入式 8004 系列专为在最严苛的嵌入式环境中表现出色而打造,非常适合网络系统、路由器、安全设备、企业和云温/冷存储以及工业边缘应用,从而确保无缝处理动态工作负载。 突破
[嵌入式]
AMD 面向<font color='red'>嵌入式系统</font>推出高能效 EPYC 嵌入式 8004 系列
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved