|
楼主 |
发表于 2021-12-23 00:58:01
|
显示全部楼层
最新的OB算法文件,ST留下一个缺陷,写完选项字后实际未校验。
其实可以通过读取Flash内容完成校验工作,而不是读寄存器值校验(寄存器只有在断电再上电后才会更新的)
/*
* Verify Flash Contents
* Parameter: adr: Start Address
* sz: Size (in bytes)
* buf: Data
* Return Value: (adr+sz) - OK, Failed Address
*/
#ifdef FLASH_OPT
unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf) {
#if 0 /* verify does not work because I do not get the registers updated without a reset! */
#if defined STM32G0x0
u32 optr = *((u32 *)(buf + 0));
u32 wrp1ar = *((u32 *)(buf + 4));
u32 wrp1br = *((u32 *)(buf + 8));
#if defined FLASH_DB
u32 wrp2ar = *((u32 *)(buf + 12));
u32 wrp2br = *((u32 *)(buf + 16));
#endif
#endif // STM32G0x0
#if defined STM32G0x1
u32 optr = *((u32 *)(buf + 0));
u32 wrp1ar = *((u32 *)(buf + 4));
u32 wrp1br = *((u32 *)(buf + 8));
u32 pcrop1asr = *((u32 *)(buf + 12));
u32 pcrop1aer = *((u32 *)(buf + 16));
u32 pcrop1bsr = *((u32 *)(buf + 20));
u32 pcrop1ber = *((u32 *)(buf + 24));
u32 secr = *((u32 *)(buf + 28));
#if defined FLASH_DB
u32 wrp2ar = *((u32 *)(buf + 32));
u32 wrp2br = *((u32 *)(buf + 36));
u32 pcrop2asr = *((u32 *)(buf + 40));
u32 pcrop2aer = *((u32 *)(buf + 44));
u32 pcrop2bsr = *((u32 *)(buf + 48));
u32 pcrop2ber = *((u32 *)(buf + 52));
#endif
#endif /* STM32G0x1 */
FLASH->SR = FLASH_PGERR; // Reset Error Flags
FLASH->CR = FLASH_OBL_LAUNCH; // Load Option Bytes -> generates a reset!
__DSB();
#if defined STM32G0x0
if ((FLASH->OPTR & 0x3F7FFFFF) != (optr & 0x3F7FFFFF)) { // Check OPTR values
return (adr + 0);
}
if ((FLASH->WRP1AR & 0x007F007F) != (wrp1ar & 0x007F007F)) { // Check WRP1AR values
return (adr + 1);
}
if ((FLASH->WRP1BR & 0x007F007F) != (wrp1br & 0x007F007F)) { // Check WRP1BR values
return (adr + 2);
}
#if defined FLASH_DB
if ((FLASH->WRP2AR & 0x007F007F) != (wrp2ar & 0x007F007F)) { // Check WRP2AR values
return (adr + 3);
}
if ((FLASH->WRP2BR & 0x007F007F) != (wrp2br & 0x007F007F)) { // Check WRP2BR values
return (adr + 4);
}
#endif
#endif /* STM32G0x0 */
#if defined STM32G0x1
if ((FLASH->OPTR & 0x3F7FFFFF) != (optr & 0x3F7FFFFF)) { // Check OPTR values
return (adr + 0);
}
if ((FLASH->WRP1AR & 0x007F007F) != (wrp1ar & 0x007F007F)) { // Check WRP1AR values
return (adr + 1);
}
if ((FLASH->WRP1BR & 0x007F007F) != (wrp1br & 0x007F007F)) { // Check WRP1BR values
return (adr + 2);
}
if ((FLASH->PCROP1ASR & 0x000001FF) != (pcrop1asr & 0x000001FF)) { // Check PCROP1ASR values
return (adr + 3);
}
if ((FLASH->PCROP1AER & 0x800001FF) != (pcrop1aer & 0x800001FF)) { // Check PCROP1AER values
return (adr + 4);
}
if ((FLASH->PCROP1BSR & 0x000001FF) != (pcrop1bsr & 0x000001FF)) { // Check PCROP1BSR values
return (adr + 5);
}
if ((FLASH->PCROP1BER & 0x000001FF) != (pcrop1ber & 0x000001FF)) { // Check PCROP1BER values
return (adr + 6);
}
if ((FLASH->SECR & 0x0FF100FF) != (secr & 0x0FF100FF)) { // Check SECR values
return (adr + 7);
}
#if defined FLASH_DB
if ((FLASH->WRP2AR & 0x007F007F) != (wrp2ar & 0x007F007F)) { // Check WRP2AR values
return (adr + 8);
}
if ((FLASH->WRP2BR & 0x007F007F) != (wrp2br & 0x007F007F)) { // Check WRP2BR values
return (adr + 9);
}
if ((FLASH->PCROP2ASR & 0x000001FF) != (pcrop2asr & 0x000001FF)) { // Check PCROP2ASR values
return (adr + 10);
}
if ((FLASH->PCROP2AER & 0x800001FF) != (pcrop2aer & 0x800001FF)) { // Check PCROP2AER values
return (adr + 11);
}
if ((FLASH->PCROP2BSR & 0x000001FF) != (pcrop2bsr & 0x000001FF)) { // Check PCROP2BSR values
return (adr + 12);
}
if ((FLASH->PCROP2BER & 0x000001FF) != (pcrop2ber & 0x000001FF)) { // Check PCROP2BER values
return (adr + 13);
}
#endif
#endif /* STM32G0x1 */
#endif
return (adr + sz); --固定返回OK,实际没校验
}
#endif /* FLASH_OPT */
|
|