好东西就是要来分享的:
昨天准备熟悉一下STM32内部Flash功能,不小心把flash设置了读保护,芯片不能烧写程序不能仿真调试,无奈只能想办法解除读保护。读保护也能用来程序加密,因为解除读保护的同时flash全部填充0xff别人也就拿不走你的代码。
一、 设置读保护
函数库方法:
int main(void){ FLASH_Unlock();
FLASH_ReadOutProtection(ENABLE);
while(1);}
就是这么简单你的片子就挂掉了。
寄存器方法:
这个麻烦一点,你要先读flash数据手册,然后了解flash寄存器,然后总之挺麻烦
大体步骤如下:擦除键值FPEC——擦除OPEKEYR键值(CR-OPTWRE自动置一又自动清零)——OPTER置位(允许写选择字节)——STRT置位(擦除选择字节)——清除OPTER——OPTPG烧写选择字节——OB->RDP写字节。然后你的片子就挂掉了
int main(void)
{ FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB; //擦除键值FPEC
while(FLASH->SR&0x00000001);
FLASH->OPTKEYR = 0x45670123;
FLASH->OPTKEYR = 0xCDEF89AB;
FLASH->CR |= (1<<5); //OPTER=5
FLASH->CR |= (1<<6); // STRT=6
while(FLASH->SR&0x00000001);
FLASH->CR &= ~(1<<5);
FLASH->CR |= (1<<4); //OPTER=5
OB->RDP = 0x0000; //
while(FLASH->SR&0x00000001);
FLASH->CR &=~ (1<<4); //OPTER=5
二、 解除读保护
问题来了,芯片已经设置了读保护,不能下载程序,不能仿真调试。想要解除读保护就得让解除程序在芯片运行,保护知识针对flash的操作,RAM并不受影响,所以只需要把程序在RAM运行就可以了。
下面介绍MDK下RAM调试设置方法:
全部是设置options for target 里面内容
1. 选择芯片型号,我用的是device ——STM32F13C8T6
2. Target: IROM1: 0x20000000 0x2000
IRAM1: 0X20002000 0X3000
我的芯片是20K容量的内部SRAM 一部分存放程序,一部分存变量
以往在flash运行程序的时候程序是放在flash内部的,这里把程序放在ram里面,另外开辟一部分ram存放变量
3. Linker设置
主要是设置存放程序和变量位置的起始地址
下面scatter file 的文件内容要与ram的分配相匹配
下面贴上我的代码:
LR_IROM1 0x20000000 0x00002000 { ; load region size_region
ER_IROM1 0x20000000 0x00002000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20002000 0x00003000 { ; RW data
.ANY (+RW +ZI)
}
}
4设置debug:
Load application at startup选项去掉勾选。
其中ini文件内容需要自己写主要重定向SP.PC指针
下面帖ini文件内容:
FUNC void Setup (void) {
SP = _RDWORD(0x20000000); // Setup Stack Pointer
PC = _RDWORD(0x20000004); // Setup Program Counter
_WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register
}
LOAD STM32_RAM_RUN.axf INCREMENTAL // 这个axf文件要换成自己的
Setup(); // Setup for Running
g, main
5设置utilities
去掉Update target before debugging 勾选
点击settings
如图设置
RAM for Algorithm 开始地址是前面设置的IRAM1的起始地址,大小也是那个的大小。下面那个programming algorithm可以不选,我这里还是flash的地址呢,因为咱们是操作SRAM所以这个没有影响。
设置完之后可以仿真程序,不是下载,不好用也不要着急。我测试了一上午不好用总是出错,中午吃完饭回来把工程重新建立,设置一边就好了,最终也不知道是什么原因。运行之后打开反汇编窗口会发现程序停在0x20000000以后的地址上
到这里我们SRAM调试程序已经设置成功。想要解除读保护也就不难了,把解除读保护的放在main函数里运行就OK了
下面贴程序
函数库版本:
比较简单int main(void)
{
FLASH_Unlock();
FLASH_ReadOutProtection(ENABLE);
while(1);
}
寄存器版本:操作与设置读保护一样,知识把OB->RDP的值改变一下变为0x00A5;
int main(void)
{
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB; //擦除键值FPEC
while(FLASH->SR&0x00000001);
FLASH->OPTKEYR = 0x45670123;
FLASH->OPTKEYR = 0xCDEF89AB;
FLASH->CR |= (1<<5); //OPTER=5
FLASH->CR |= (1<<6); // STRT=6
while(FLASH->SR&0x00000001);
FLASH->CR &= ~(1<<5);
FLASH->CR |= (1<<4); //OPTER=5
OB->RDP = 0x0000; //
while(FLASH->SR&0x00000001);
FLASH->CR &=~ (1<<4); //OPTER=5
总结:文笔有限,SRAM看不明白可以问度娘网上很多方法,读保护和解除读保护是在看不懂就用函数库的把,简单方便,寄存器的看不明白请仔细研读flash手册。比较苦恼的就是MDK里面没有找到监测FLASH寄存器的窗口哪位大神如果知道还请告诉小弟一声。
邮箱baozitai@163.com,有啥问题可以问我
一周热门 更多>