11965|16

56

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

stm32f103rc设置读保护后不能正常运行??? [复制链接]



MCU型号:STM32F103RC。
问题:设置读保护后程序不能正常运行。
操作:
1、一个能够正常运行的程序,没有对前4KB代码空间进行写入操作。使用j-link进行secure操作后不能正常运行。之后进行unsecure,重新装载代码,不进行secure操作,运行正常。
2、在代码中加入读保护指令(先解锁,再修改RDP由0xA5到0x11,重启),运行不正常。取消读出保护指令,unsecure芯片,重新烧入代码,运行正常。

清版主指导一下,可能是什么原因?
这个问题我已经搞了一整天了。。。。。
此帖出自stm32/stm8论坛

最新回复

                                 讨论过程,也是大家学习的过程,很不错  详情 回复 发表于 2010-1-29 15:01
点赞 关注
 

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
                                 怀疑你在操作读保护的选项字节时,写入了其他的选项字节。你可以读出所有的选项字节,对照手册看看是否有不应该设置的部分。
此帖出自stm32/stm8论坛
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
                                 呵呵  他已经置了读保护,怎么读出数据呢。
此帖出自stm32/stm8论坛
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

4
 
读保护只限制通过程序之外的手段读出Flash的内容,并不限制从程序中读出。

只要写一个小程序,只包含较少的内容,测试一下就知道了。
此帖出自stm32/stm8论坛
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

5
 


版主的主意不错,问题有些进展,情况如下:
在没有读保护时,读出的option bytes是正确的(RDP是0xA5,Data0被我使用,是0x1E,其它是0xff)。使用j-link加上读保护后,读出的option bytes,RDP是0xff,Data0也成了0xff。分析可能是j-link把整个option bytes都擦除了。
于是我在程序中加入Data0检测功能,如果发现其不是0x1e,则修改成0x1e,并在修改前后都打印出option bytes的内容。之后测试中发现在没有读保护时,Data0可以从0xff修改成0x1E,有读保护时,Data0总是0xff。
我的程序中使用到这个Data0,它引导程序加载,看来读保护后程序不能运行就是因为Data0不正常造成的。
请版主看看我的分析是否正确,如果是,那该如何在写保护后还能修改Data0、Data1???
下面是相关的代码:
int main()
{
    。。。

    OB_TypeDef obTmp;
    obTmp = *OB;  //读出选项字节,保存在临时缓冲区
   
    if(((u8)(OB->Data0) != 0x1e) && ((u8)(OB->Data0) != 0x2d)) { //(u8*)0x1ffff804
      printf("last\r\n");
      printf("OB->RDP=0x%x\r\n", OB->RDP);
      printf("OB->USER=0x%x\r\n", OB->USER);
      printf("OB->Data0=0x%x\r\n", OB->Data0);
      printf("OB->Data1=0x%x\r\n", OB->Data1);
      printf("OB->WRP0=0x%x\r\n", OB->WRP0);
      printf("OB->WRP1=0x%x\r\n", OB->WRP1);
      printf("OB->WRP2=0x%x\r\n", OB->WRP2);
      printf("OB->WRP3=0x%x\r\n", OB->WRP3);
      delay1ms(200);
      
      //FLASH_Unlock();
      FLASH_EraseOptionBytes();
      FLASH_ProgramOptionByteData((u32)(&(OB->Data0)), 0x1e);  //0x1ffff804
      //恢复其它的option bytes
      FLASH_ProgramOptionByteData((u32)(&(OB->RDP)), obTmp.RDP);  //0x1ffff800
      FLASH_ProgramOptionByteData((u32)(&(OB->USER)), obTmp.USER);  //0x1ffff802
      FLASH_ProgramOptionByteData((u32)(&(OB->Data1)), obTmp.Data1);  //0x1ffff806
      FLASH_ProgramOptionByteData((u32)(&(OB->WRP0)), obTmp.WRP0);  //0x1ffff808
      FLASH_ProgramOptionByteData((u32)(&(OB->WRP1)), obTmp.WRP1);  //0x1ffff80a
      FLASH_ProgramOptionByteData((u32)(&(OB->WRP2)), obTmp.WRP2);  //0x1ffff80c
      FLASH_ProgramOptionByteData((u32)(&(OB->WRP3)), obTmp.WRP3);  //0x1ffff80e
      
      //FLASH_WaitForLastOperation(0xfff);
      //FLASH_Lock();
      printf("last2\r\n");
      printf("OB->RDP=0x%x\r\n", OB->RDP);
      printf("OB->USER=0x%x\r\n", OB->USER);
      printf("OB->Data0=0x%x\r\n", OB->Data0);
      printf("OB->Data1=0x%x\r\n", OB->Data1);
      printf("OB->WRP0=0x%x\r\n", OB->WRP0);
      printf("OB->WRP1=0x%x\r\n", OB->WRP1);
      printf("OB->WRP2=0x%x\r\n", OB->WRP2);
      printf("OB->WRP3=0x%x\r\n", OB->WRP3);
      delay1ms(200);
      NVIC_GenerateSystemReset();
    }

    printf("next\r\n");
    printf("OB->RDP=0x%x\r\n", OB->RDP);
    printf("OB->USER=0x%x\r\n", OB->USER);
    printf("OB->Data0=0x%x\r\n", OB->Data0);
    printf("OB->Data1=0x%x\r\n", OB->Data1);
    printf("OB->WRP0=0x%x\r\n", OB->WRP0);
    printf("OB->WRP1=0x%x\r\n", OB->WRP1);
    printf("OB->WRP2=0x%x\r\n", OB->WRP2);
    printf("OB->WRP3=0x%x\r\n", OB->WRP3);
    delay1ms(200);
    。。。。。。。
}
此帖出自stm32/stm8论坛
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

6
 


应该在没有设置保护的情况下,写入Option bytes。

基本过程是:
1)解除保护
2)掉电
3)上电
4)擦除Option bytes
5)设置保护,同时设置Option bytes
6)掉电
7)上电

上述的2)、3)和6)、7)的掉电和上电过程是非常必要的。


上述过程可以实现需要的操作,但是有更简单的操作方式,请看13楼的说明。对由此引起的误会和造成的麻烦,表示道歉。
此帖出自stm32/stm8论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

7
 
                                 为什么要这样反复的掉电上电呢
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

8
 
为什么要这样反复的掉电上电呢
因为Option bytes的内容只有在上电时才被读到内部的寄存器,而真正起作用的是内部寄存器的内容。如果修改了Option bytes的配置,在没有重新上电之前,新的配置内容不会被刷新到内部寄存器中,因此它不能起作用。
此帖出自stm32/stm8论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(中级)

9
 
应该在没有设置保护的情况下,写入Option bytes。
版主,你说的这种约束条件在ST的datasheet中找不到相关的支持,datasheet是否要及时更新一下。我一向都是先仔细研究文档,然后再动手写代码,资料要不完整,那就太折腾人了,你说是不?
如果是这样,那这边Data0 Data1的作用就打折扣了,我的程序就不能使用这两个变量了。只能在Flash中令开一个区间来代替。
最后,谢谢版主!
此帖出自stm32/stm8论坛
 
 
 

回复

19

帖子

0

TA的资源

一粒金砂(初级)

10
 
“应该在没有设置保护的情况下,写入Option bytes。”

因为我没有动手做过,这一点我不敢十分肯定,我需要测试一下再说。

另外,我看到5楼给出的程序中,为什么你把FLASH_Unlock()那行注释掉了,是否会因为这个原因造成不能写入呢?
此帖出自stm32/stm8论坛
 
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

11
 
哦,是这样。
注释掉Flash_Unlock()是因为测试中发现它没有任何作用,并且在坛子里也看到相关的描述。ST的资料上说是要先解锁以启动FPEC,并且上电复位之后是自动加锁的(从写main Flash的操作能够看出来,如果没有解锁操作,main Flash是写不进任何数据的),看来写main flash和写option bytes不同的,这里应该是是资料说错了。
另外我觉得这里的解锁操作应该和读保护没有关系的。
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

12
 
哦,是这样。
注释掉Flash_Unlock()是因为测试中发现它没有任何作用,并且在坛子里也看到相关的描述。ST的资料上说是要先解锁以启动FPEC,并且上电复位之后是自动加锁的(从写main Flash的操作能够看出来,如果没有 ...
我不这么认为,写Option bytes之前也是要进行解锁操作的。

在《STM32F10xxx闪存编程手册》(PM0042)中的第2.4.3节说明了这一点:

2.4.3 选项字节块写保护
默认状态下,选项字节块始终是可以读且被写保护。要想对选项字节块进行写操作(编程/擦除)首先要在OPTKEYR中写入正确的键序列(与上锁时一样),随后允许对选项字节块的写操作,FLASH_CR寄存器的OPTWRE位标示允许写,清除这位将禁止写操作。

你把FLASH_Unlock()那行恢复了再试试看?

STM32_Option_Byte_Protection.gif (10.27 KB)

STM32_Option_Byte_Protection.gif

此帖出自stm32/stm8论坛
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

13
 
因为之前没有进行实际测试,仅凭楼主的描述,误以为写Option bytes也需要解除Flash的写保护。

今天我们按照楼主的需求进行了测试,证实手册中的描述是准确地,只要在写Option bytes之前,按照12楼的描述解开对Option byte block的写保护,就可以写入Option bytes中的Data0,这个操作与整个Flash区的写保护是否存在无关。

估计楼主的问题有2种可能,1)写Option byte之前没有解除Option byte block的写保护;2)写入Data0之前,Data0的内容不是0xFFFF。请再检查一下。
此帖出自stm32/stm8论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

14
 
下面是我在5楼的代码节选:
     FLASH_EraseOptionBytes();
      FLASH_ProgramOptionByteData((u32)(&(OB->Data0)), 0x1e);  //0x1ffff804
      //恢复其它的option bytes
      FLASH_ProgramOptionByteData((u32)(&(OB->RDP)), obTmp.RDP);  //0x1ffff800
。。。 。。。
请看代码,我是先擦除,再写Data,再恢复其它的内容。在函数FLASH_EraseOptionBytes()和FLASH_ProgramOptionByteData()的内部都是有Option bytes区解锁的操作,(这是ST的库函数)。所以我不认为存在没有解锁和Data0不是0xffff的情况。
另外,我还有一点奇怪的,修改Option bytes之后,软件复位竟然不管用,一定要掉电、上电才会正常运行???这样就给使用带来很大的不便,远程断电有时候不容易做到。
此帖出自stm32/stm8论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

15
 
“我还有一点奇怪的,修改Option bytes之后,软件复位竟然不管用,一定要掉电、上电才会正常运行”

这并不奇怪,在STM32F10xxx编程手册中写得很清楚:如果在设置了读保护时,调试器仍然连接到JTAG/SWD接口,需要执行一次上电复位,而不是(没有调试器时的)系统复位。

而在STM32参考手册中也说明了:软件复位属于一种系统复位。

STM32_RDP.GIF (19.8 KB)

STM32_RDP.GIF

STM32_System_Reset.GIF (29.56 KB)

STM32_System_Reset.GIF

此帖出自stm32/stm8论坛
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

16
 
嗯,知道了。我当时看datasheet时可能没有注意到这个Note。
谢谢啦。
我现在已经改用Flash中的一个页来代替Option bytes 中的Data0,反正Flash也有富余,1个page无所谓的。读保护测试也没问题,对我这个项目,这样就OK了。
由于时间的原因,关于在读保护之后,Option bytes中的Data0修改的问题,以后有需要再来研究。
再次感谢版主!
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

17
 
                                 讨论过程,也是大家学习的过程,很不错
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表