uint32_t StartPage = 0, EndPage = 0, StartBank = 0, EndBank = 0;
static FLASH_OBProgramInitTypeDef OptionsBytesStruct, OptionsBytesStruct2;
static uint32_t GetPage(uint32_t Address);
static uint32_t GetBank(uint32_t Address);
void app_ob_flash_write(rt_uint32_t startaddr, rt_uint32_t endaddr)
{
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
/* Clear OPTVERR bit set on virgin samples */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
/* Unlock the Options Bytes *************************************************/
HAL_FLASH_OB_Unlock();
/* Get the number of the start and end pages */
StartPage = GetPage(startaddr);
EndPage = GetPage(endaddr);
/* Get the bank of the start and end pages */
StartBank = GetBank(startaddr);
EndBank = GetBank(endaddr);
if (StartBank == EndBank)
{
/* WRP area is only on one bank */
if (StartBank == FLASH_BANK_1)
{
OptionsBytesStruct.WRPArea = OB_WRPAREA_BANK1_AREAA;
OptionsBytesStruct2.WRPArea = OB_WRPAREA_BANK1_AREAB;
}
else
{
OptionsBytesStruct.WRPArea = OB_WRPAREA_BANK2_AREAA;
OptionsBytesStruct2.WRPArea = OB_WRPAREA_BANK2_AREAB;
}
}
else
{
goto _exit;
}
/* Get pages write protection status ****************************************/
HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);
HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct2);
/* write option bytes**************************/
/* Check if desired pages are not yet write protected ***********************/
if ((OptionsBytesStruct.WRPStartOffset <= StartPage) && (OptionsBytesStruct.WRPEndOffset >= (StartPage - 1)))
{
/* Current area is adjacent to pages to be write protected */
if (OptionsBytesStruct.WRPEndOffset < EndPage)
{
/* Current area will be extended to include the pages to be write protected */
OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct.WRPEndOffset = EndPage;
}
}
else if ((OptionsBytesStruct.WRPStartOffset <= (EndPage + 1)) && (OptionsBytesStruct.WRPEndOffset >= EndPage))
{
/* Current area is adjacent to pages to be write protected */
if (OptionsBytesStruct.WRPStartOffset > StartPage)
{
/* Current area will be extended to include the pages to be write protected */
OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct.WRPStartOffset = StartPage;
}
}
else if ((OptionsBytesStruct.WRPStartOffset > StartPage) && (OptionsBytesStruct.WRPEndOffset < EndPage))
{
/* Current area is included in pages to be write protected */
OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct.WRPStartOffset = StartPage;
OptionsBytesStruct.WRPEndOffset = EndPage;
}
else if ((OptionsBytesStruct2.WRPStartOffset <= StartPage) && (OptionsBytesStruct2.WRPEndOffset >= (StartPage - 1)))
{
/* Current area is adjacent to pages to be write protected */
if (OptionsBytesStruct2.WRPEndOffset < EndPage)
{
/* Current area will be extended to include the pages to be write protected */
OptionsBytesStruct2.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct2.WRPEndOffset = EndPage;
}
}
else if ((OptionsBytesStruct2.WRPStartOffset <= (EndPage + 1)) && (OptionsBytesStruct2.WRPEndOffset >= EndPage))
{
/* Current area is adjacent to pages to be write protected */
if (OptionsBytesStruct2.WRPStartOffset > StartPage)
{
/* Current area will be extended to include the pages to be write protected */
OptionsBytesStruct2.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct2.WRPStartOffset = StartPage;
}
}
else if ((OptionsBytesStruct2.WRPStartOffset > StartPage) && (OptionsBytesStruct2.WRPEndOffset < EndPage))
{
/* Current area is included in pages to be write protected */
OptionsBytesStruct2.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct2.WRPStartOffset = StartPage;
OptionsBytesStruct2.WRPEndOffset = EndPage;
}
else if (OptionsBytesStruct.WRPStartOffset > OptionsBytesStruct.WRPEndOffset)
{
/* Current area is not used => it will be configured to protect the pages */
OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct.WRPStartOffset = StartPage;
OptionsBytesStruct.WRPEndOffset = EndPage;
}
else if (OptionsBytesStruct2.WRPStartOffset > OptionsBytesStruct2.WRPEndOffset)
{
/* Current area is not used => it will be configured to protect the pages */
OptionsBytesStruct2.OptionType = OPTIONBYTE_WRP;
OptionsBytesStruct2.WRPStartOffset = StartPage;
OptionsBytesStruct2.WRPEndOffset = EndPage;
}
else
{
/* No more area available to protect the pages */
/* => Error : not possible to activate the pages indicated */
goto _exit;
}
/*write option bytes**************************/
if (OptionsBytesStruct.OptionType == OPTIONBYTE_WRP)
{
if (HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK)
{
goto _exit;
/* Error occurred while options bytes programming. **********************/
}
}
if (OptionsBytesStruct2.OptionType == OPTIONBYTE_WRP)
{
if (HAL_FLASHEx_OBProgram(&OptionsBytesStruct2) != HAL_OK)
{
goto _exit;
/* Error occurred while options bytes programming. **********************/
}
}
_exit:
/* Lock the Options Bytes *************************************************/
HAL_FLASH_OB_Lock();
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
HAL_FLASH_Lock();
}
void app_ob_flash_launch(void)
{
if ((OptionsBytesStruct.OptionType == OPTIONBYTE_WRP) || (OptionsBytesStruct2.OptionType == OPTIONBYTE_WRP))
{
LOG_I("write protect launch");
/* Unlock the Flash to enable the flash control register access *************/
HAL_FLASH_Unlock();
/* Clear OPTVERR bit set on virgin samples */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
/* Unlock the Options Bytes *************************************************/
HAL_FLASH_OB_Unlock();
HAL_FLASH_OB_Launch();
/* Lock the Options Bytes *************************************************/
HAL_FLASH_OB_Lock();
/* Lock the Flash to disable the flash control register access (recommended
to protect the FLASH memory against possible unwanted operation) *********/
HAL_FLASH_Lock();
}
}
/**
* @brief Gets the page of a given address
* @param Addr: Address of the FLASH Memory
* @retval The page of a given address
*/
static uint32_t GetPage(uint32_t Addr)
{
uint32_t page = 0;
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
{
/* Bank 1 */
page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}
else
{
/* Bank 2 */
page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
}
return page;
}
/**
* @brief Gets the bank of a given address
* @param Addr: Address of the FLASH Memory
* @retval The bank of a given address
*/
static uint32_t GetBank(uint32_t Addr)
{
uint32_t bank = 0;
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0)
{
/* No Bank swap */
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
{
bank = FLASH_BANK_1;
}
else
{
bank = FLASH_BANK_2;
}
}
else
{
/* Bank swap */
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
{
bank = FLASH_BANK_2;
}
else
{
bank = FLASH_BANK_1;
}
}
return bank;
}
int flash_ob_test(void)
{
app_ob_flash_write(0x08000000, 0x0801f800);
app_ob_flash_write(0x08020000, 0x0803c000);
app_ob_flash_launch();
return 0;
}
STM32L系列写保护设置
发布于 2020-09-10 575 次阅读
