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

【经验分享】STM32F4xx PCROP 功能使用说明

[复制链接]
STMCU小助手 发布时间:2022-2-27 16:13
一.前言
Proprietary Code Read Out Protection (PCROP) ----- 专有代码读取保护
现在产品开发过程中,二次开发将会越来越多,设计公司开发出自己产品后交给终端客户进行二次功能或补充开发,简称二次开发,设计公司某些程序代码不希望公开给终端客户,但同时又希望部分函数功能可以给终端客户使用,这时就需要有一种专有代码保护机制供客户使用,STM32F4xx 芯片中的PCROP 可以解决类似问题。

二.PCROP 简要描述
PCROP 功能在 STM32F42xxx 和 STM32F43xxx 芯片中包含,当使用 PCROP 时,用户扇区(0--23)Flash 能够阻止 D-Bus 的读取指令;保护功能选择通过 FLASH_OPTCR 寄存器的 SPRMOD 选择位进行选择:
• SPRMOD = 0: nWRPi 用于控制用户扇区写保护
• SPRMOD = 1: nWRPi 用于控制 PCROP 读写保护
当 PCROP 功能使能时:
任何通过 D-Buss 的读取动作将会有 RDERR 错误标志
任何对 PCROP 保护的扇区的擦除/写入操作将会有 WRPERR 错误标志
PCROP 保护等级设定如下:

UC~11F4LAVD{{DQX2_DQA{7.png

三. 如何使用 PCROP 功能
1. 需要使用 6.50 以上版本的 EWARM(IAR),使能 C/C++ Complier --> Code--> No data reads in code memory ;

}T03QT${}$UBKH%G]9IQ.png

2. 修改 stm32f4xx_flash.icf 文件,定义 PCROP 保护的地址空间;

CQX%({ACC2YGBG2DWM8{12Q.png

   本文使用 STM32F429NIH6 芯片的 0x08008000---0x0800BFFF(Sector 2)作为 PCROP 保护区域,stm32f4xx_flash.icf 修改如下:
  1.    /*###ICF### Section handled by ICF editor, don't touch! ****/
  2.    /*-Editor annotation file-*/
  3.    /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
  4.    /*-Specials-*/
  5.    define symbol __ICFEDIT_intvec_start__ = 0x08000000;
  6.    /*-Memory Regions-*/
  7.    define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
  8.    define symbol __ICFEDIT_region_ROM_end__ = 0x08003FFF;
  9.    define symbol __ICFEDIT_region_CODE_start__ = 0x08008000;
  10.    define symbol __ICFEDIT_region_CODE_end__ = 0x0800BFFF;

  11. define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
  12. define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF;
  13. define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;
  14. define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF;
  15. /*-Sizes-*/
  16. define symbol __ICFEDIT_size_cstack__ = 0x400;
  17. define symbol __ICFEDIT_size_heap__ = 0x200;
  18. /**** End of ICF editor section. ###ICF###*/
  19. define memory mem with size = 4G;
  20. define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to
  21. __ICFEDIT_region_ROM_end__];
  22. define region CODE_region = mem:[from __ICFEDIT_region_CODE_start__ to
  23. __ICFEDIT_region_CODE_end__];
  24. define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to
  25. __ICFEDIT_region_RAM_end__];
  26. define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to
  27. __ICFEDIT_region_CCMRAM_end__];
  28. define region TabCode = [from 0x08004000 to 0x08007FFF];
  29. place in TabCode { ro section .tab, };
  30. define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
  31. define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
  32. initialize by copy { readwrite };
  33. do not initialize { section .noinit };
  34. place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
  35. place in CODE_region {section .CODE_Flash};
  36. place in ROM_region { readonly };
  37. place in RAM_region { readwrite,
  38. block CSTACK, block HEAP };
复制代码

3. 修改 startup file (.s)文件 Reset_Handler 中 LDR 修改为 BLX:
  1. Reset_Handler
  2. LDR R0, =SystemInit
  3. BLX R0
  4. LDR R0, =__iar_program_start
  5. BX R0
  6. 修改为:
  7. Reset_Handler
  8. BLX SystemInit
  9. BLX __iar_program_start
复制代码

4. 定义程序到 PCROP 保护区域中:
   本文实例文件 Sector_Test.c 中定义 Light_Togger()函数定义在 0x08008000-0x0800BFFF 区域:
  1.    #include "stm32f4xx.h"
  2.    #pragma location = ".CODE_Flash"
  3.    void Light_Toggle(void)
  4.    {
  5.    GPIOG->BSRRH = GPIO_Pin_6 | GPIO_Pin_7;
  6.    }
复制代码

5. 使用 STVP 对 OPTION BYTE 进行编程,使能 PCROP,并且选择保护区域:

7TIC5AGWX0A`SB7XN9KX3YV.png

此时可以读取下 0x08008000---0x0800BFFF 区域的数据,可以看到改 PCROP 空间数据不可读,但程序依然可以调用该区域函数---- Light_Togger()

]RUOY[W~QY~O_D}SPG1)IPD.png

四.本文所用测试代码说明以及代码

Main 函数作为客户程序代码,而需要调用的函数 Light_Togger()位于 PCROP 保护区域(0x08008000---0x0800BFFF),实现 GPIOG_6/GPIOG_7 端口的 Toggle;
Main.c 文件如下:
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "main.h"
  3. extern void Light_Toggle(void);
  4. int main(void)
  5. {
  6. unsigned int i;
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. /* GPIOG Peripheral clock enable */
  9. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
  10. /* Configure PG6 and PG8 in output pushpull mode */
  11. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  13. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  16. GPIO_Init(GPIOG, &GPIO_InitStructure);

  17. while(1)
  18. {
  19. GPIOG->BSRRL = GPIO_Pin_6 | GPIO_Pin_7;
  20. i = 0xFFFFFF;
  21. while(i--);
  22. Light_Toggle();

  23. i = 0xFFFFFF;
  24. while(i--);
  25. }
  26. }
复制代码

Sector_Test.c 如下:
  1. #include "stm32f4xx.h"
  2. #pragma location = ".CODE_Flash"
  3. void Light_Toggle(void)
  4. {
  5. GPIOG->BSRRH = GPIO_Pin_6 | GPIO_Pin_7;
  6. }
复制代码


收藏 评论0 发布时间:2022-2-27 16:13

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版