一、芯片对于内部FLASH的保护措施 据我所了解的大部分芯片都会提供对FLASH的保护,用于防止外部在没有被允许的情况下随意地对FLASH进行操作(其中包括了读保护和写保护)。 读保护从简单字面意义上来讲,就是保护FLASH数据不轻易被读取到,保护用户的隐私;当读保护被解除或者FLASH被强行读取时,芯片会自动擦除整个FLASH,起到保护数据的作用。 当读保护生效时,CPU执行程序可以读受保护的FLASH区,但也有两个例外: 1)调试执行程序时; 2)从RAM启动并执行程序时。(这是因为芯片在对FLASH的存储区添加读保护之后,就算用户未启用写保护,FLASH的前四页也会处于写保护状态,这是为了防止修改复位或中断向量而跳转到RAM区执行非法程序代码) 二、关于读保护的想法按正常操作来说,配置读保护是先通过FLASH选项字擦除,再对其配置操作为读保护。若在擦除选项字后,芯片意外掉电,那此时的芯片是否处于读保护状态? 三、想法验证本次验证已APM32F103VBT6作为参考。(图片见附录PDF) 1)修改库函数的初始化,将读保护地址给到的数据5AA5给屏蔽掉,验证选项字擦除后是否能进入读保护; 2)编写相应程序,验证想法。 3)通过上述验证,可以知道芯片即使在擦除后意外掉电,未能执行FLASH读保护配置也是可以实现读保护的。 四、主函数代码int main(void) { uint8_t i; GPIO_Config_T GPIO_ConfigStruct; USART_Config_T USART_ConfigStruct; APM_MINI_LEDInit(LED2); APM_MINI_LEDInit(LED3); RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_USART1)); //按键配置 GPIO_Config_T GPIO_PA1; GPIO_PA1.mode = GPIO_MODE_IN_PU; GPIO_PA1.pin = GPIO_PIN_2; GPIO_Config(GPIOA,&GPIO_PA1); GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP; GPIO_ConfigStruct.pin = GPIO_PIN_9; GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz; GPIO_Config(GPIOA, &GPIO_ConfigStruct); USART_ConfigStruct.baudRate = 115200; USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE; USART_ConfigStruct.mode = USART_MODE_TX; USART_ConfigStruct.parity = USART_PARITY_NONE; USART_ConfigStruct.stopBits = USART_STOP_BIT_1; USART_ConfigStruct.wordLength = USART_WORD_LEN_8B; USART_Config(USART1, &USART_ConfigStruct); USART_Enable(USART1); SysTick_Config(SystemCoreClock / 1000); uint32_t OB_COUNT = 0; OB_COUNT = FMC->OBCS; printf("FLASH_OBR = 0X%08X\r\n",OB_COUNT); //选项字擦除 if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_2) == 1) { FMC_Unlock(); FMC_EraseOptionBytes(); FMC_Lock(); } printf("读保护状态:0X%08X\r\n",*(uint32_t*)(0x1FFFF800)); while(1) { Delay(); if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_2) == 0) { APM_MINI_LEDToggle(LED3); printf("失能读保护\r\n"); Delay(); FMC_Unlock(); FMC_DisableReadOutProtection(); FMC_Lock(); printf("FLASH擦除\r\n"); } printf("IO翻转\r\n"); APM_MINI_LEDToggle(LED2); } }
|