0
点赞
收藏
分享

微信扫一扫

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能


STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现解除读保护

目录

  • ​​STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现解除读保护​​
  • ​​1、介绍​​
  • ​​2、KEIL配置实现代码下载进SRAM​​
  • ​​3、HAL库解除/设置读保护代码实现​​

开发环境:

  • keil-mdk
  • stm32f103c8
  • stm32cubemx

1、介绍

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_STM32读保护

一般情况下,我们在KEIL-MDK中开发时,调试下载程序默认是把程序下载进FLASH中运行的,CODE和RW-data的内容被写进FLASH存储,单片机掉电数据不会丢失。

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_STM32_02

但是在调试阶段存在大量的程序下载、程序调试,一方面下载进FLASH比较慢,尤其开发比较大的STM32程序时;另一方面对FLASH频繁擦写造成的磨损减少了其使用寿命。那么此时我们就可以将程序直接下载进内存(SRAM)中去运行调试,既下载的快又有效的保护了FLASH的寿命。

除去加快调试的目的,还有一个作用就是可以利用keil将代码下载进内存,从而实现解除写保护!

在项目完工交付阶段或者实现了量产,为了保护芯片内的程序不被别人非法拷贝,芯片一般会在出厂时开启读保护,要么在代码中加入,要么在烧录程序后人工通过软件开启该功能,比如STM32 ST-LINK Utility,当然,也可以使用该工具关闭读保护功能。

但这样会导致一个麻烦的问题:无法正常调试

如果每次都使用STM32 ST-LINK Utility软件或者JFLASH软件去解锁FLASH,那就太麻烦了。下面就介绍一种使用KEIL-MDK来解除读保护的方法。

先说一下读保护的原理:

设置读保护功能是通过设置相应的Option Bytes来实现的,并且掉电不会消失。

而解除读保护是则是复位相应的Option Bytes来实现,掉电也不会消失。

但不同的是,解除读保护设置完之后,芯片自动会擦除整颗芯片,这样就不能通过解除读保护进而读取整颗芯片代码了,顾就实现了程序的非法读取保护。

此时,你会发现,虽然无法读取FLASH,但是却可以通过调试器连接上它,那么我们就可以通过配置keil的一些设置,将代码下载进RAM中运行,而下载进RAM的这段代码中就包含着解除读保护的程序!

2、KEIL配置实现代码下载进SRAM

具体操作步骤如下:

首先新建一个编译目标:

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_代码实现_03

然后重新选择一个编译输出目录:

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_代码实现_04

然后在设置一下链接地址,使代码下载进SRAM中:

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_SRAM启动_05


接下来新建一个Debug_RAM.ini的配置文件:

该文件在目录E:\install\Keil_v5\Packs\Keil\STM32F1xx_DFP\2.3.0\Boards\Keil\MCBSTM32C\Blinky\中存在,可以直接拷贝过来!

该文件内容如下:

/*----------------------------------------------------------------------------
* Name: Debug_RAM.ini
* Purpose: RAM Debug Initialization File
* Note(s):
*----------------------------------------------------------------------------
* This file is part of the uVision/ARM development tools.
* This software may only be used under the terms of a valid, current,
* end user licence from KEIL for a compatible version of KEIL software
* development tools. Nothing else gives you the right to use this software.
*
* This software is supplied "AS IS" without warranties of any kind.
*
* Copyright (c) 2008-2011 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
Setup() configure PC & SP for RAM Debug
*----------------------------------------------------------------------------*/
FUNC void Setup (void) {
SP = _RDWORD(0x20000000); // Setup Stack Pointer
PC = _RDWORD(0x20000004); // Setup Program Counter
_WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register
}

FUNC void OnResetExec (void) { // executes upon software RESET
Setup(); // Setup for Running
}

load %L incremental

Setup(); // Setup for Running

g, main

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_STM32_06


STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_STM32_07

新增这两个宏定义:​​VECT_TAB_SRAM​​​,​​USER_VECT_TAB_ADDRESS​

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_STM32读保护_08

最后通过宏定义进行条件编译:

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_代码实现_09

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_STM32读保护_10

编译,然后点击Debug即可。

此时,程序应该自动停止在断点处 __breakpoint(0),这说明解除代码已经顺利运行完成!

STM32CubeMX | 利用KEIL将代码下载能进内存(SRAM)实现RAM启动调试代码、解除读保护(Read Protection)功能_MDK_11

经过这样设置后,每次需要解除芯片读保护功能时,只要切换目标后即可成功解除(前提是已经编译过一次了),非常方便,省去了再去使用STM32 ST-LINK Utility软件的麻烦!

3、HAL库解除/设置读保护代码实现

void FLASH_SetReadProtectionState(int state)
{
FLASH_OBProgramInitTypeDef OptionsBytesStruct;
HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);

HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();

if(state)
{
if(OptionsBytesStruct.RDPLevel == OB_RDP_LEVEL0)
{
OptionsBytesStruct.OptionType = OPTIONBYTE_RDP;
OptionsBytesStruct.RDPLevel = OB_RDP_LEVEL1;
HAL_FLASHEx_OBProgram(&OptionsBytesStruct);
}
}
else
{
if(OptionsBytesStruct.RDPLevel == OB_RDP_LEVEL1)
{
OptionsBytesStruct.OptionType = OPTIONBYTE_RDP;
OptionsBytesStruct.RDPLevel = OB_RDP_LEVEL0;
HAL_FLASHEx_OBProgram(&OptionsBytesStruct);
}
}

HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
}

ends…


举报

相关推荐

0 条评论