STM32/STM8技术论坛
直播中

邹壮志

5年用户 18经验值
私信 关注
[问答]

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;
	}
	
}

更多回帖

发帖
×
20
完善资料,
赚取积分