|
在“使用Kinetis K22微控制器Flash内置USB-HID引导程序的方法”文章中,我介绍了如何使用tinyK22(或FRDM-K22F)的Flash内置USB HID引导程序。为确保加载的应用程序不会以某种方式损坏,使用循环冗余校验和(CRC)对其进行验证非常重要。KBOOT Bootloader可以验证这种CRC,但如何生成一个CRC以及如何使用它并不是很明显,所以本文主要介绍了如何生成该CRC。
内容简介 本文介绍如何从二进制文件和S-Record文件中计算KBOOT的CRC32,以及如何将值插入BCA(引导加载程序配置区)。另外它提供了关于调试引导加载应用程序的一些提示。
引导程序配置区(BCA) 引导加载程序配置有BCA(引导加载程序配置区)。它将配置ROM引导加载程序。对于KL03Z,ROM引导程序没有实现校验功能:-(,所以我必须构建一个Flash内置的bootloader。
对于Flash内置引导加载程序,BCA也会加载部分应用程序,并且位于位于偏移量为0x0000的向量表之后的偏移量0x3C0处。
所以如果应用程序在0xC000下载(如本教程中所用),则BCA位于0xC3C0。 BCA可以以C语言的结构体形式实现,或者它可以是汇编代码的一部分,例如在本教程中的启动文件中:
CRC起始地址,以字节为单位的大小和预期的CRC值位于标签字节的后面: ● 0x3c0 + 0x4:[04:07] crcStartAddress ● 0x3c0 + 0x8:[08:0b] crcByteCount ● 0x3c0 + 0xC:[0c:0f] crcExpectedValue
问题是:如何计算预期的CRC值?
使用KinetisFlashTool的CRC值 计算预期CRC值的一种可能实现的方法是使用KinetisFlashTool。在该工具中,浏览二进制(.bin)文件(唯一支持的格式),然后点击Config按钮:
在对话框中,启用CRC校验,并填写二进制文件的镜像地址:
单击OK,这些值将会显示在BCA HEX字段中:
但这是一个非常痛苦的过程,并且只适用于.bin(二进制)文件。
计算S-Record文件的CRC 一种更好的方法是使用srec_cat实用程序: - srec_cat tinyK22_KBOOT_led_demo.srec -fill 0xff 0xc000 0xd000 -crop 0xc400 0xD000 -Bit_Reverse -CRC32LE 0x1000 -Bit_Reverse -XOR 0xff -crop 0x1000 0x1004 -Output - -hex_dump
复制代码
Robert Poor(见https://community.nxp.com/thread/462397),他找到了正确的命令行来生成KBOOT所需的CRC32。 ■ - fill 0xFF 0xC000 0xD000:用0xff填充0xC400..0xD000的内存 ■ -crop 0xc400 0xD000:只保留CRC计算的区域。这不包括向量表和BCA本身 ■ -Bit_Reverse -CRC32LE 0x1000 -Bit_Reverse -XOR 0xff:用于根据KBOOT的预期生成正确的CRC32并将其存储到给定地址 ■ -crop 0x1000 0x1004 -Output -HEX_DUMP:裁剪生成的CRC32的所有内容并将输出转储到控制台。
理想情况下,0xC000处的向量表和0xC3C0处的BCA将被包含在CRC中,但KBOOT不支持这一点,所以为了简单起见,我将它从CRC计算中排除。
要找出大小,请使用链接器映射文件或使用srec_info:
输出类似以下内容: - Format: Motorola S-Record
- Header: "tinyK22_KBOOT_led_demo.srec"
- Execution Start Address: 0000C4D9
- Data: C000 - CA2B
复制代码
然后产生类似的: - srec_cat tinyK22_KBOOT_led_demo.srec -fill 0xff 0xc000 0xd000 -crop 0xc400 0xd000 -Bit_Reverse -CRC32LE 0x1000 -Bit_Reverse -XOR 0xff -crop 0x1000 0x1004 -Output - -hex_dump
- 00001000: D6 88 C6 B4 #V.F4
复制代码
意思是CRC32是0xD688C6B4。
然后该值同字节数和起始地址一起写入源代码中,类似于:
但是,这需要重新编译应用程序。所以更简单的方法是直接将CRC32添加到.srec文件中: - srec_cat -generate 0xc3cc 0xc3d0 -constant-l-e 0xD688C6B4 4 tinyK22_KBOOT_led_demo.srec -exclude 0xc3cc 0xc3d0 -Output_Block_Size 16 -output newWithCRC32.srec
复制代码
然后使用KinetisFlashTool加载新文件:
在Bootloader中,可以在bl_app_crc_check.c中的函数is_application_crc_check_pass()中调试CRC校验:
CRC32与二进制文件 以下是如何在二进制文件内显示BCA的CRC字段: - srec_cat tinyK22_KBOOT_led_demo.bin -binary -crop 0x3c0 0x3d0 -output - -hex_dump
复制代码
然后输出: - 000003C0:6B 63 66 67 00 C4 00 00 00 0C 00 00 B4 C6 88 D6#kcfg.D ...... 4F.V
复制代码
要从二进制文件中计算CRC32值,我使用以下命令行: - srec_cat tinyK22_KBOOT_led_demo.bin -binary -fill 0xff 0x0000 0x1000 -crop 0x0400 0x1000 -Bit_Reverse -CRC32LE 0x1000 -Bit_Reverse -XOR 0xff -crop 0x1000 0x1004 -Output - -hex_dump
- 00001000: 52 04 06 B8 #.c^B
复制代码
它首先用0xff填充符从0x0000到0x1000的内存,然后截取0x400到0x1000之间的区域,计算校验和并在控制台上输出它。
然后将其添加到二进制文件。以下是将该CRC32值插入到偏移量为0x3C4的二进制文件中的命令行: - srec_cat -generate 0x3cc 0x3d0 -constant-b-e 0x52E406B8 4 tinyK22_KBOOT_led_demo.bin -binary -exclude 0x3cc 0x3d0 -output newWithCRC32.bin -Binary
复制代码
CRC检查和“软件”断点调试 在引导加载程序中完成CRC计算有一个潜在的问题:如果您的调试程序仿真修改闪存以设置断点(例如,Segger J-Link可以执行此操作以获得'无限'断点),则这会改变代码,并因此使CRC校验和/校验无效。因此,如果加载和CRC校验应用程序代码,请确保您没有在该区域设置任何断点。
自动化 本文介绍手动确定CRC值的步骤,并将其添加到应用程序中。要使用Python脚本实现自动化,请参阅Robert Poor的工作,网址为https://github.com/rdpoor/srec-crc。
总结 在引导加载程序中添加CRC32检查使得该过程更加可靠,因为它可以检测加载映像中的位。知道正确的多项式和CRC计算方式并不能总是解决问题的。Robert Poor发现了如何为KBOOT创建CRC32。我现在可以从S19和二进制文件生成校验和。我正在做半自动化的事情(计算CRC并将其插入到文件中),如果我有时间,我会打算进一步实现自动化。在此之前,请参看Robert如何实现自动化。
参考链接 ■ 本教程在GitHub上使用的项目:https://github.com/ErichStyger/m ... xamples/KDS/tinyK22 ■ 使用Kinetis K22微控制器Flash内置USB-HID引导程序的方法:https://www.yiboard.com/thread-793-1-1.html ■ 为KBOOT生成CRC-32(Robert Poor):https://community.nxp.com/thread/462397 ■ 如何自动生成CRC(Robert Poor):https://github.com/rdpoor/srec-crc |