完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在上一章节中我们介绍了RAM检测的实现方法,本章节我们将给大家介绍FLASH检测的实现方法。 测试Flash存储器完整性时,需要用到CRC校验,在参考代码中我们使用了硬件的CRC单元,通过硬件CRC生成器完成的CRC计算大大降低CPU负载。 Flash存储器测试的范围由用户界定,在运行时,如果整个内存范围因测试时间太长而不能接受,用户可将其分成若干片段,Flash存储器测试范围由用户界定,我们需要对被测试区域进行动态修改,以便在那些区域单独执行测试。 检查区域的边界必须与测试中用到的多重测试块的大小一致。根据mm32_STLparam.h文件中定义的参数FLASH_BLOCK_WORDS,块大小默认设为16字( 64字节),检查中未使用的内存区域可通过预定义值来识别。 我们会将CRC校验值存储在某一个地址,然后将CRC计算结果与相应的参考值进行比较,参考模式可由编译器( IAR™)自动提供或由在外部计算后由最终用户添加( MDK-ARM®和AC6)。 在ClassB检测中,Flash存储器检测也分为启动自检与运行自检两部分。 启动时对FLASH的检测方法: 编译时计算整个FLASH的CRC校验值,并存储在FLASH末尾位置 启动时,用同样的算法重新计算整个FLASH的CRC校验值(不包括前面存储在FLASH中的CRC校验值),并与存储在FLASH中的CRC校验值做比较 函数为: void STL_StartUp(void); 运行时对FLASH的检测方法: 对FLASH分块逐次计算出最终的CRC校验值 将最终结果与正确的CRC校验值做比较 函数为: ClassBTestStatus STL_crc32Run(void);01 FLASH验证方法 FLASH的验证分为2个步骤,如下所示: 1. 读取PC端计算FLASH对应的CRC值。 2. MCU运行计算出来的CRC值与读取到的PC端计算的CRC值进行比较。 1.1 设置IAR生成CRC 1、IAR可以很方便的支持在编译时计算CRC32,并存储在FLASH指定位置。
Fill unused code memory:定义了FLASH中需要计算CRC的范围和空闲字节填充值; 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进行迭代。 2、指定checksum在FLASH中的存储位置——修改linker文件: place at end of ROM_region { ro section .checksum }; 1.2 设置Keil生成CRC脚本 在Keil中需要单独计算CRC的值,并手动添加代码将其放在FLASH末尾。 当MDK在工程编译完成以后会在option for target ->User页面下面,勾选After build/Rebuild中的Run#1选项,则会在工程编译完成以后执行After build/Rebuild中的Run#1选项后面User Command路径选择中选择的脚本(crc_gen_keil.bat脚本)。
SREC_PATH:设定工具路径; TARGET_NAME:生成Hex文件名; MAP_FILE:原始生成的map文件; INPUT_FILE:原始生产的HEX文件; OUTPUT_FILE:计算CRC后的CRC文件; crc_gen_keil.bat脚本内容: REM Path configuration SET SREC_PATH=C:SREC SET TARGET_NAME=CLASSBTEST SET TARGET_PATH=OBJ SET BYTE_SWAP=1 SET COMPARE_HEX=1 SET CRC_ADDR_FROM_MAP=1 REM Not used when CRC_ADDR_FROM_MAP=1 SET CRC_ADDR=0x08007ce0 执行SET批处理命令,将相关的文件赋值给相对应的变量。 REM Derived configuration SET MAP_FILE=%TARGET_PATH%%TARGET_NAME%.map SET INPUT_HEX=%TARGET_PATH%%TARGET_NAME%.hex SET OUTPUT_HEX=%TARGET_PATH%%TARGET_NAME%_CRC.hex SET TMP_FILE=crc_tmp_file.txt 通过srec_cat.exe工具查找map文件中的__check_sum地址,并把计算的新的CRC的值填入到这个地址。 1.3 在启动文件中设置CRC校验 AREA CHECKSUM, DATA, READONLY, ALIGN=6 EXPORT __Check_Sum ALIGN __Check_Sum DCD 0x8A7A061D; END 1.4 配置硬件CRC MM32的CRC初始化配置较简单,使能CRC时钟,复位 CRC 计算单元即可。 RCC_AHBPeriphClockCmd(RCC_AHBENR_CRCEN,ENABLE); CRC_ResetDR(); 计算CRC的数值: for(index = 0; index < (uint32_t)ROM_SIZEinWORDS; index++) { CRC->DR = __REV(*((uint32_t *)ROM_START + index)); } crc_result = CRC->DR; 02 MCU运行中计算FLASH中的CRC 把要计算的FLASH大小分成多块累计计算CRC。 uint32_t index; for(index = 0; index < (uint32_t)FLASH_BLOCK_WORDS; index++) { CRC->DR = __REV(*(pRunCrc32Chk + index)); } pRunCrc32Chk += FLASH_BLOCK_WORDS; pRunCrc32ChkInv = ((uint32_t *)~((uint32_t)pRunCrc32Chk)); result = TEST_RUNNING; 2.1 MCU运行中计算的CRC的数值与PC端计算的CRC数值进行比较 如果两者计算的CRC的数值相同则FLASH验证通过,否则验证失败。 启动时对比结果: #if defined(__CC_ARM) || defined(__GNUC__) if(crc_result != *(uint32_t *)(&REF_CRC32)) #endif { #ifdef STL_VERBOSE_POR printf("FLASH 32-bit CRC Error at Start-upnr"); #endif /* STL_VERBOSE_POR */ FailSafePOR(); //for ROM test realse must open; //control_flow_resume(CRC_TEST_CALLER); } else { /* Test OK */ #ifdef STL_VERBOSE_POR printf(" Start-up FLASH 32-bit CRC OKnr"); #endif /* STL_VERBOSE_POR */ control_flow_resume(CRC_TEST_CALLER); } 运行时对比结果: if(CRC->DR == *(uint32_t *)(&REF_CRC32)) { result = TEST_OK; } else { //result = TEST_OK ; // for ROM test realse must open;******* result = TEST_FAILURE; } 如果该块的FLASH检测通过,则进行下一次的检测,循环这一个过程。 至此,FLASH的校验已经全部完成,具体的配置程序可以参考官网例程。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2248个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11676 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5922 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
10953 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4571 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4297 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
964浏览 1评论
792浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 04:52 , Processed in 0.567940 second(s), Total 40, Slave 32 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号