你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

OPTION BYTE 全部锁死的问题

[复制链接]
574997859 提问时间:2019-10-16 11:18 /
我在程序里边加入了修改选项字节的功能,以达到程序自动启用芯片读出保护以及扇区写保护,防止扇区数据被误写。但是设备在使用的过程中,经常出现死机的情况,具体情况为,芯片锁死,不再启动,所有的扇区写保护均已开启。具体的,我猜测是读写保护的那一个寄存器为0,看门狗配置选项的寄存器也为0了,大家可以看图片。
QQ截图20191022102214.jpg

拿到设备,读取选项字节的参数,就如上图所示。芯片不能启动,不会工作,断电再上电也一样。
--------------------------------------------------------------------

QQ截图20191016111100.jpg
在我调试的过程中,我发现,程序在读写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();
        }
               
}


QQ截图20191016110712.jpg
收藏 评论4 发布时间:2019-10-16 11:18

举报

4个回答
574997859 回答时间:2019-10-18 14:42:02
没人了吗?
butterflyspring 回答时间:2019-10-31 12:19:51
改一个这个试试看 if( (UsrCfgVal & 0x01 ||  RDP_StaVal) == RESET ) 。
574997859 回答时间:2019-12-2 09:34:42
butterflyspring 发表于 2019-10-31 12:19
改一个这个试试看 if( (UsrCfgVal & 0x01 ||  RDP_StaVal) == RESET ) 。

现场反馈会锁死,但是测试中不会。我们是工控产品。
butterflyspring 回答时间:2019-12-4 11:02:49
那就要看看现场是否有什么不一样的情况了,通常工业现场环境复杂,但对于解决问题来说最直接发现,当然很辛苦

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版