标题:
32单片机软件ROM自检程序怎么写?
[打印本页]
作者:
zouzhuangzhi
时间:
2023-2-13 15:42
标题:
32单片机软件ROM自检程序怎么写?
现在在做一款32位单片机软件自检程序,在做ROM的CRC校验自检时遇到问题,认证公司要求先把程序的CRC校验值写到FLASH固定地址里面(该地址不做CRC校验),进入自检的时候程序进行CRC计算,然后与放在FLASH固定地址的CRC比较来检验ROM区域的程序是否有异常变化,自己写了程序应该是有BUG,有大佬提供一下例程不?
// 引用外部函数extern uint32_t iec60730_ram_march_bist_test(uint32_t addr);extern void iec60730_reg_r1_r4_bist_test(void);extern void iec60730_reg_r0_bist_test(void);extern void iec60730_reg_r8_r12_bist_test(void);extern void iec60730_reg_sp_bist_test(void);extern void iec60730_reg_spec_bist_test(void);extern void iec60730_reg_lr_bist_test(void);extern void iec60730_pc_test(void);extern CPUStatus STL_RunTimeCPUTest(void);void PC_Test_Func1(void)__attribute__((section(".ARM.__at_0x00003ff0"))); //地址以4为单位递增,不然编译不通过,函数声明需要放在文件最上面声明void PC_Test_Func2(void)__attribute__((section(".ARM.__at_0x0000400c"))); const uint32_t CRC_Result __attribute__((at(0x00007F8C))) = 0x00006EFF;uint32_t RamTestResult = 0;uint32_t CpuTestResult = 0;uint32_t crcResult = 0;/*flash self test*/static uint32_t _FLASH_CRC;// 栈底数据__IO uint32_t StackOverFlowPtrn[4] __attribute__((section("STACK_BOTTOM"), zero_init));// 每次校验的数据量#define ROM_BIST_SIZE 8 /* 8 bytes every time */#define ROM_START (0x0)#define FLASH_ROM_START_ADDR (0x0)#define FLASH_ROM_SIZE (20480)//(32*1024)//#define FLASH_ROM_SIZE (32*1024)#define ROM_END ((uint32_t)(FLASH_ROM_SIZE - 1))#define ROM_SIZE ((uint32_t)ROM_END - (uint32_t)ROM_START + 1)static volatile uint32_t hw_crc,sw_crc;// bref: 测试flash// para:// note:static void ROM_Test(void){ stl_uint8_t* p_flash_start_addr = (stl_uint8_t*)FLASH_ROM_START_ADDR; iec_test_result.rom_test_result = IEC_TEST_SUCCESS; CRC_Init(); /*open crc apb clock*/ SYS_EnablePeripheralClk(SYS_CLK_CRC_MSK); /* use hardware CRC16 to calculate expected crc first, then verify if the CRC code calculated by software is same with expected crc */ hw_crc = IEC60730_HardwareCRC16Gen(p_flash_start_addr, ROM_SIZE); if(IEC60730_TEST_NORMAL != IEC60730_SoftwareCRC16Test(p_flash_start_addr, ROM_SIZE, hw_crc)){ iec_test_result.rom_test_result = IEC_TEST_FAIL; } // 使用过硬件CRC 完成一个完整的校验 选哟重新初始化 CRC_Init(); /* use software CRC16 to calculate expected crc first, then verify if the CRC code calculated by hardware is same with expected crc */ sw_crc = IEC60730_SoftwareCRC16Gen(p_flash_start_addr, ROM_SIZE); if(IEC60730_TEST_NORMAL != IEC60730_HardwareCRC16Test(p_flash_start_addr,ROM_SIZE, sw_crc)){ iec_test_result.rom_test_result = IEC_TEST_FAIL; } // 记录整个flash 区域的校验值 _FLASH_CRC = hw_crc; crcResult = CRC_Result; if(crcResult == sw_crc)//_FLASH_CRC CRC_Result { iec_test_result.rom_test_result = IEC_TEST_SUCCESS; } else { iec_test_result.rom_test_result = IEC_TEST_FAIL; } }
作者:
hi等你
时间:
2023-2-15 16:14
程序rom还能自检?本人才疏学浅,一般单片机程序稍大一些1k起步,再大几十k够大了,如何自检每个字节
甚至每个位能无差错?用什么原理,拭目以待等候高手出现
作者:
ningsy
时间:
2023-2-15 16:53
STP ISP 在读入hex文件那一刻,已经对整个hex进行校验计算了。
捕获.PNG
(22.39 KB, 下载次数: 18)
下载附件
2023-2-15 16:53 上传
作者:
罗程峰8200
时间:
2023-2-15 22:19
理论上只要程序正常运行,程序就是对的,如果还要较验的话有什么意义?会不会被人故意刁难?
作者:
ningsy
时间:
2023-2-15 23:15
我自己写的eeprom连续读写代码,每次存入12个字节。第一位是序号,第2~11位是数据,第12位是校验位。读的时候校验一次,有问题就读默认数据。目的是为了防止eeprom写入错误,比如存储单元损坏,或写入时意外断电等。虽然几率很小,但有预案总比没有强。
作者:
ningsy
时间:
2023-2-16 19:27
按照我的理解,所谓校验就是按地址顺序读出这段数据,然后计算(比如累加求和),再与已存在的校验位比较,一致就是哪都没错往下走;不一致就报错或者B计划。应该几句代码就搞定了,为何被你写的如此复杂?
作者:
新昌小徐
时间:
2023-2-19 00:11
CRC较验啊,浙大中控,在工程师站编好程序后,编译下载到控制站,下载好后,再回读,进行CRC较验,得到CRC较验值与编译好后下载前计算出来的CRC较验值进行比较,如果相等,下载到控制站的程序无误。
同时,这次回读生成的CRC较验值将保存起来,下次编译后要下载的时候,将当前的程序的CRC较验值与上次保存的CRC值比较,如果相等,提示程序没有变化,无须下载,如果不相等,提示下载后会改变原来的程序,是否继续。
CRC较验就是用商定好的一个数据作为除数,待较验的数据作为被除数,进行除法运算,除法运算的时候没有进位和借位
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1