OPTION BYTE 全部锁死的问题
我在程序里边加入了修改选项字节的功能,以达到程序自动启用芯片读出保护以及扇区写保护,防止扇区数据被误写。但是设备在使用的过程中,经常出现死机的情况,具体情况为,芯片锁死,不再启动,所有的扇区写保护均已开启。具体的,我猜测是读写保护的那一个寄存器为0,看门狗配置选项的寄存器也为0了,大家可以看图片。拿到设备,读取选项字节的参数,就如上图所示。芯片不能启动,不会工作,断电再上电也一样。
--------------------------------------------------------------------
在我调试的过程中,我发现,程序在读写flash的时候,可能由于读取的字节没有对齐,从而导致了,Flash报错的情况下,类似于WRPERR,OPERR之类的错误出现的时候,继续进行选项字节的操作,就会导致这类的问题发生,于是,我就在操作选项字节的时候,先查询错误状态寄存器,将其清空后,再写入。但一样还是出现了死机的情况。
-------------------------------------------------------------------
该问题曾请教ST专业技术人员未果,所以来论坛找高手来了。
我下面将部分代码贴出来。
【清除错误标志】
/////////////////////////////////////////////////////////////////////////////////
void ClearErrorFlag()
{
FLASH_Status Sta = FLASH_GetStatus();
while( FLASH_COMPLETE != Sta )
{
if( Sta == FLASH_ERROR_WRP )
{
FLASH_ClearFlag(FLASH_FLAG_WRPERR);
}
if( Sta == FLASH_ERROR_RD )
{
FLASH_ClearFlag(FLASH_FLAG_RDERR);
}
if( Sta == FLASH_ERROR_OPERATION )
{
FLASH_ClearFlag(FLASH_FLAG_OPERR);
}
if( Sta == FLASH_ERROR_PROGRAM )
{
FLASH_ClearFlag(FLASH_FLAG_PGSERR);
FLASH_ClearFlag(FLASH_FLAG_PGPERR);
FLASH_ClearFlag(FLASH_FLAG_PGAERR);
}
if( Sta == FLASH_ERROR_PGS )
{
FLASH_ClearFlag(FLASH_FLAG_PGSERR);
}
if( Sta == FLASH_ERROR_PGP )
{
FLASH_ClearFlag(FLASH_FLAG_PGPERR);
}
if( Sta == FLASH_ERROR_PGA )
{
FLASH_ClearFlag(FLASH_FLAG_PGAERR);
}
Sta = FLASH_GetStatus();
}
}
【设置选项字节】
/////////////////////////////////////////////////////////////////////////////////
void SetOptionByteWRP(const uint32_t Address, FunctionalState NewState)
{
uint32_t GetValue;//*(__IO uint16_t*)OPTCR_BYTE2_ADDRESS
uint32_t OB_WRP;
MarkType WRP_AddrMark;
ClearErrorFlag();
//传入地址错误判断,直接返回,不操作
WRP_AddrMark = GetWRP_Sector(Address, &OB_WRP);
if( MarkNull == WRP_AddrMark )
{
return;
}
//验证保护扇区标志
if( !IS_OB_WRP(OB_WRP) )
{
return;
}
//读取当前要设置的片区写保护状态寄存器
if( Mark1 == WRP_AddrMark )
{
GetValue = *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS;
}
else if( Mark2 == WRP_AddrMark )
{
GetValue = *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS;
}
//读取要设定的扇区标志 0:Active 1:Inactive
GetValue = (GetValue & OB_WRP)?DISABLE:ENABLE;
if( GetValue != NewState )
{
FLASH_WaitForLastOperation();
FLASH_OB_Unlock();
if( Mark1 == WRP_AddrMark )
{
FLASH_OB_WRPConfig(OB_WRP, NewState);
}
else if( Mark2 == WRP_AddrMark )
{
FLASH_OB_WRP1Config(OB_WRP, NewState);
}
while( FLASH_COMPLETE != FLASH_OB_Launch() );
FLASH_OB_Lock();
FLASH_WaitForLastOperation();
}
}
【设置硬狗等选项字节】
/////////////////////////////////////////////////////////////////////////////////
void OptionByte_Other_Program(void)
{
uint8_t UsrCfgVal = FLASH_OB_GetUser();
FlagStatus RDP_StaVal = FLASH_OB_GetRDP();
if( UsrCfgVal & 0x01 ||RDP_StaVal == RESET )
{
FLASH_OB_Unlock();
if( UsrCfgVal & 0x01 )
{
FLASH_WaitForLastOperation();
FLASH_OB_UserConfig(OB_IWDG_HW, OB_STOP_RST, OB_STDBY_NoRST);
FLASH_WaitForLastOperation();
}
if( RDP_StaVal == RESET )
{
FLASH_WaitForLastOperation();
FLASH_OB_RDPConfig(OB_RDP_Level_1);
FLASH_WaitForLastOperation();
}
while( FLASH_COMPLETE != FLASH_OB_Launch() );
FLASH_OB_Lock();
}
}
没人了吗? 改一个这个试试看 if( (UsrCfgVal & 0x01 ||RDP_StaVal) == RESET ) 。 butterflyspring 发表于 2019-10-31 12:19
改一个这个试试看 if( (UsrCfgVal & 0x01 ||RDP_StaVal) == RESET ) 。
现场反馈会锁死,但是测试中不会。我们是工控产品。 那就要看看现场是否有什么不一样的情况了,通常工业现场环境复杂,但对于解决问题来说最直接发现,当然很辛苦:)
页:
[1]