内置CRC于hex程序中的方法

本文介绍了如何在程序中内置CRC32值,以避免因程序更新导致CRC值变化的问题。通过详细分析CRC算法和修正过程,提供了一种将CRC域和修正值(TAIL)进行位操作的方法,确保程序更新后CRC值保持不变。此外,还讨论了自动计算、功能扩展和效果评价,提供了完整的代码示例。
摘要由CSDN通过智能技术生成

【摘要】

  为了让MCU程序显示自身的CRC值,需要将其内置到程序中。但是,通常情况下,用计算好的CRC值,代替程序中原有的默认值之后,会导致程序发生变动,进而引发CRC值的变动。最终,新程序显示的值,是旧程序的CRC值。

1、问题原因分析

  首先要说明一下,为什么要内置CRC值到程序中。
  把程序分成两个hex文件,一个是普通的程序,另一个单独使用Flash的一页,并将CRC值放置在其中,每次下载两个hex文件,不行吗?这方法本身是可行的,但是,为了显示CRC值,而使用Flash的一页,太浪费了。而且,软件入库时,入2个hex文件,生产部门下载时,也要下载2个hex文件,太麻烦了。
  那么,通过上位机把CRC值传给MCU,并保存到EEPROM之类的地方,不行吗?这方法不但麻烦,而且不是所有的板子都带外扩存储器。
  既然上述方法那么麻烦,那么让MCU自己去计算CRC值,不行吗?这方法的问题就更多了。我们的大前提,要求MCU计算出的CRC值,与通过校验码软件算出的CRC值,二者必须一致。
是,二者有信息不对等的弊病。MCU无法得到hex文件,因此无法知道程序的准确大小,当然也无法知道在Flash内的内容中,哪些是正常的程序,哪些是在hex文件中不存在而自动填充的0xFF(通称窟窿),哪些是使用J-Link下载时未擦除而残余的其他程序。再来看校验码软件,软件读取hex文件,通常可以知道Flash区的起始地址,但一般无法知道Flash的容量。让用户敲Flash容量?既然MCU中可能会存在未擦干净的其他程序,那么校验码软件就算知道了Flash容量,又有什么意义呢。所以,让MCU自己去计算CRC值,是不现实的。

  所以,最后还是选择内置CRC值到程序中,问题在于修正程序使CRC值不变。

2、修正值

  之前写的典型案例《指定CRC反构数据》,给出了一种方法,通过修改文件中任意位置的连续4字节,可以得到任意指定的CRC32值。我们的校验码软件,是在CRC32的基础上,改造为适合于hex文件的算法,因此其核心仍然是CRC32,可以通过类似的方法进行修正。这种方法,需要新建一个工具,或者修改校验码软件,由软件处理最终的hex文件,然后把CRC值和修正值,全部传回源文件,再重新编译。但是问题来了,CRC值放在哪个地址?修正值放在哪个地址?让软件工程师自己敲?总而言之,这不是最好的办法。
  虽然IAR自带了一个CRC计算的工具,并能够嵌入到目标程序中的指定位置,但那并不能生成与我们的校验码软件一致的CRC值,因此我们至少必须把CRC值传回源文件,再重新编译。问题在于,如何让源代码自动计算修正值。实际上,我们不必遍历完整的hex文件。只要找到CRC值和修正值的对应关系,并且二者挨在一起,那么不论放在什么地址,都不会影响最终的CRC值。这个方法是目前为止的最好办法。
  我们拿十进制的数学余数来展示原理,二进制的逻辑余数的原理是类似的。
  举例:数字12300004560000789对61的余数,结果是23。我们可以把“23”这两个数,替换到数字中4个0的位置,并在之后填充修正值。修正值是多少呢?算一下2300对61的余数,结果是43,与61的差值为18,因此修正值就是18。把余数和修正值连在一起,就是2318,这个数不论填在前面4个0的位置(12323184560000789),还是填在后面4个0的位置(12300004562318789),甚至全填(12323184562318789),这几个数对61的余数仍然是23。原因很简单,2318对61的余数是零,因此不论2318后面添几个零,加到原数上都不影响其余数。

3、CRC32修正值

  CRC32算法采用的多项式(POLY)为0x04C11DB7,颠倒之后为0xEDB88320。为什么要颠倒?因为这个CRC32算法,在处理字节中的各个位的时候,采用的是从低位开始向高位依次处理的方法,与我们直观的从高到低的处理方法相反,所以把多项式颠倒过来。位的序号也要颠倒过来看。颠倒之后,以二进制形式表示,就是:

0

7

8

15

16

23

24

31

1

1

1

0

1

1

0

1

1

0

1

1

1

0

0

0

1

0

0

0

0

0

1

1

0

0

1

0

0

0

0

0

(画表格真难)

  同样,我们把CRC域,以及修正值(以下称为TAIL)域也按位展开,并添零:

0

7

8

15

16

23

24

31

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

7

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值