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

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

[复制链接]
STMCU小助手 发布时间:2022-2-27 16:13
一.前言
: d. v" g4 E5 T; OProprietary Code Read Out Protection (PCROP) ----- 专有代码读取保护
4 D; u/ n- _' b+ l/ {6 _$ [现在产品开发过程中,二次开发将会越来越多,设计公司开发出自己产品后交给终端客户进行二次功能或补充开发,简称二次开发,设计公司某些程序代码不希望公开给终端客户,但同时又希望部分函数功能可以给终端客户使用,这时就需要有一种专有代码保护机制供客户使用,STM32F4xx 芯片中的PCROP 可以解决类似问题。
" V* T9 M6 A$ _7 g  V+ g( }3 U' W6 y. D3 E3 N  r
二.PCROP 简要描述
4 S' h( ?) e/ K  v0 A+ k; u$ |PCROP 功能在 STM32F42xxx 和 STM32F43xxx 芯片中包含,当使用 PCROP 时,用户扇区(0--23)Flash 能够阻止 D-Bus 的读取指令;保护功能选择通过 FLASH_OPTCR 寄存器的 SPRMOD 选择位进行选择:
: ~( e# U8 n9 T+ f• SPRMOD = 0: nWRPi 用于控制用户扇区写保护
5 Z8 V" ]4 E9 r2 p• SPRMOD = 1: nWRPi 用于控制 PCROP 读写保护" y7 M8 O# x. W# J' J) D
当 PCROP 功能使能时:+ D5 j8 m/ a: {0 _* \( A% ]
任何通过 D-Buss 的读取动作将会有 RDERR 错误标志" j" o; B7 w5 {
任何对 PCROP 保护的扇区的擦除/写入操作将会有 WRPERR 错误标志* c- ]0 W. G5 I) B/ _
PCROP 保护等级设定如下:) x! D. `( U# n! R& ^
- a+ M& T  C0 M7 q$ }/ X! I) T
UC~11F4LAVD{{DQX2_DQA{7.png
5 l8 b6 o! s, j9 W& a$ A, N5 U9 U3 {) U  z6 ?2 C* J9 V
三. 如何使用 PCROP 功能
0 {9 B; U8 n, j( f1. 需要使用 6.50 以上版本的 EWARM(IAR),使能 C/C++ Complier --> Code--> No data reads in code memory ;
& E1 y3 D* e4 F' ?$ _5 H; l4 z' a7 {' ^# s4 O8 T! ~) U
}T03QT${}$UBKH%G]9IQ.png
7 K  \. x1 f( y& u
& r9 R4 e. Z7 K2. 修改 stm32f4xx_flash.icf 文件,定义 PCROP 保护的地址空间;
0 D& r9 ^; ]- e- _  n9 t8 ?0 j0 A! t
CQX%({ACC2YGBG2DWM8{12Q.png % X1 V6 G/ |7 r8 D; l

5 S* X, B4 R8 a, B" K   本文使用 STM32F429NIH6 芯片的 0x08008000---0x0800BFFF(Sector 2)作为 PCROP 保护区域,stm32f4xx_flash.icf 修改如下:: d4 ~7 a8 ^8 D! [4 g) s: Z
  1.    /*###ICF### Section handled by ICF editor, don't touch! ****/
    . w& ^, F8 F& V
  2.    /*-Editor annotation file-*/
    5 _0 V7 Z* b! J$ W
  3.    /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
    ; R% U; G7 |5 C$ `* r- Z
  4.    /*-Specials-*/
    ! m; T( G- f# ]' t9 T% v3 r
  5.    define symbol __ICFEDIT_intvec_start__ = 0x08000000;
    ) x2 c4 |4 T, Z& g1 P
  6.    /*-Memory Regions-*/
    ) Y% Q0 A& S( x# O
  7.    define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;8 @' S" g/ O0 e: {) t
  8.    define symbol __ICFEDIT_region_ROM_end__ = 0x08003FFF;
    7 C# w& A( v, @8 H2 D
  9.    define symbol __ICFEDIT_region_CODE_start__ = 0x08008000;
    & I7 [- I+ i* F6 ?8 ]4 W
  10.    define symbol __ICFEDIT_region_CODE_end__ = 0x0800BFFF;# B, @5 b: S0 Z

  11. . X& l* k& X. i" |3 z
  12. define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;$ H  p: V) w# ]
  13. define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF;
    ; n, @9 ^' a7 s
  14. define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000;# Z* U, m( p/ r
  15. define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF;
    ( f4 [- x4 a+ C# ?/ _
  16. /*-Sizes-*/
    " n3 y) A3 A8 g! W
  17. define symbol __ICFEDIT_size_cstack__ = 0x400;
    - t& g" g* V1 e4 L
  18. define symbol __ICFEDIT_size_heap__ = 0x200;% D) Y% m1 t6 T7 {
  19. /**** End of ICF editor section. ###ICF###*/
    " q. n  L# S& R% X# Q) v3 |8 V
  20. define memory mem with size = 4G;; ^. w% ?  M0 R" _0 e: f
  21. define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to& r- _/ k2 k- D. U
  22. __ICFEDIT_region_ROM_end__];1 Z/ X5 k' d3 e) x2 F( P
  23. define region CODE_region = mem:[from __ICFEDIT_region_CODE_start__ to
    ( C. p$ A5 W$ _7 x
  24. __ICFEDIT_region_CODE_end__];; I/ S9 R+ v/ u
  25. define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to
    0 \# A# {9 t4 l( F4 P( w4 k) ~
  26. __ICFEDIT_region_RAM_end__];
    1 O, A, Y# e5 M  {+ ], ~
  27. define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to
    - {* W& i& w- }3 K! k
  28. __ICFEDIT_region_CCMRAM_end__];, |; z4 [$ a" t6 f* Q/ ]4 r/ b
  29. define region TabCode = [from 0x08004000 to 0x08007FFF];
    ! `! i& x! ~% l  B, v. e
  30. place in TabCode { ro section .tab, };
    . l4 t* A! K% i( q0 p5 C" g$ W* `
  31. define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
    : |2 ?% p2 e. f' {, p8 j
  32. define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };8 o% \  I9 F  E2 t
  33. initialize by copy { readwrite };
    , G5 m5 S7 y5 a# S- m
  34. do not initialize { section .noinit };9 P5 [5 v' Y$ P
  35. place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
    8 H. }& _# @* J
  36. place in CODE_region {section .CODE_Flash};
    ' j/ n7 R- e2 q8 Y" v: G
  37. place in ROM_region { readonly };
    $ k& H. g) ^- m3 V, y, D
  38. place in RAM_region { readwrite,6 {% J. P" L0 D7 J
  39. block CSTACK, block HEAP };
复制代码
' s: |) e1 r6 u: W6 T  A
3. 修改 startup file (.s)文件 Reset_Handler 中 LDR 修改为 BLX:: b0 W& k+ s+ l/ @( n) m* [
  1. Reset_Handler
    " H! O" F4 r5 ]# C& c
  2. LDR R0, =SystemInit
    / ]& K* C% F* Y" P# P5 a
  3. BLX R02 y5 w2 L& t: a
  4. LDR R0, =__iar_program_start
    8 S$ K+ U& Z& ]. Y
  5. BX R0
    # k3 r; d* l& G' \
  6. 修改为:
    * _& R7 V8 a* x0 W  @: `
  7. Reset_Handler, ^! W' i7 L  _/ D/ p. s
  8. BLX SystemInit
    + f! q$ _9 P7 e7 \. C
  9. BLX __iar_program_start2 m0 H* l% C5 h( {
复制代码

2 A, a, u3 n0 ~, D' V) j) t4. 定义程序到 PCROP 保护区域中:
) o9 C4 x: V5 g  }, S   本文实例文件 Sector_Test.c 中定义 Light_Togger()函数定义在 0x08008000-0x0800BFFF 区域:
  u; q% ^- d' E) `$ i
  1.    #include "stm32f4xx.h"
    2 h0 n: ]& I3 N1 I' \' K, n
  2.    #pragma location = ".CODE_Flash"3 n" h7 i' c: f3 h
  3.    void Light_Toggle(void)3 u! T$ A- y0 b) `2 f7 S
  4.    {7 l0 X3 ~/ L" W$ l3 C
  5.    GPIOG->BSRRH = GPIO_Pin_6 | GPIO_Pin_7;1 y- V/ o4 f) P, r7 v
  6.    }
复制代码

4 Y% ]2 P" h. H$ [) y8 U5. 使用 STVP 对 OPTION BYTE 进行编程,使能 PCROP,并且选择保护区域:
: L( e6 v% l. s& T8 Q5 u" ?$ ~
/ |1 K! p6 X2 d4 V 7TIC5AGWX0A`SB7XN9KX3YV.png ( c/ u3 L$ B, D9 x3 }

1 F; V8 K2 z4 I' S6 K+ S1 U, ?此时可以读取下 0x08008000---0x0800BFFF 区域的数据,可以看到改 PCROP 空间数据不可读,但程序依然可以调用该区域函数---- Light_Togger()
. }' U% e4 A, {; `. |
8 e1 e+ v9 p9 @% w. r, V9 r ]RUOY[W~QY~O_D}SPG1)IPD.png ; l3 x, g5 W( E$ W( E

3 X- r* _* q( |四.本文所用测试代码说明以及代码- [4 z! E, ^5 X$ U4 d6 `
6 J8 i3 K) t, h7 Y. S# P
Main 函数作为客户程序代码,而需要调用的函数 Light_Togger()位于 PCROP 保护区域(0x08008000---0x0800BFFF),实现 GPIOG_6/GPIOG_7 端口的 Toggle;
. c$ k& ]4 {& gMain.c 文件如下:( P9 e6 Q1 l: z+ C
  1. /* Includes ------------------------------------------------------------------*/3 v. x9 _9 A- l, s( d# D
  2. #include "main.h"
    8 M# r% ~1 Q& B7 a1 j# w9 e9 x7 _
  3. extern void Light_Toggle(void);8 h; q7 \+ T5 S. q- L2 F
  4. int main(void)
    2 w" x$ i- P4 k, z
  5. {9 n* m3 k, _# \
  6. unsigned int i;
    3 c3 `2 l" O9 F+ D
  7. GPIO_InitTypeDef GPIO_InitStructure;( K- B: Z5 \. g* K; n- r1 y
  8. /* GPIOG Peripheral clock enable */4 G/ Q* m0 }+ H9 P5 h" a8 w. t" t
  9. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);2 P+ R- O# P. ^! ^
  10. /* Configure PG6 and PG8 in output pushpull mode */  \; O8 S) B3 F3 {8 m
  11. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;4 n3 T- {  p. k: D7 D! z5 i
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;# w" o* \2 l6 M7 a* U# Y, _$ S
  13. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    4 y% [, q; K& m9 E* o2 P$ c
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    & x! [& h/ q- J
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    % H# C8 D- j/ F  ^& S
  16. GPIO_Init(GPIOG, &GPIO_InitStructure);
    " p* H9 S6 H7 s; |& v
  17. 0 Y: y* W' ]6 e
  18. while(1), x9 ^7 }& [" [: Z5 k6 s
  19. {: {1 i& U8 c0 \7 m
  20. GPIOG->BSRRL = GPIO_Pin_6 | GPIO_Pin_7;# B6 w# Y& _7 K4 y& j% O2 V
  21. i = 0xFFFFFF;6 H7 R/ d+ q( ]
  22. while(i--);
    4 J. a% }5 B3 S9 f: l& N
  23. Light_Toggle();2 h. {% J; m0 g% c# q$ H4 ^* }

  24. & E& B. P, i/ u2 S) ^& E
  25. i = 0xFFFFFF;- x! s- |) H! x( w4 C1 v( T, A- T
  26. while(i--);0 u& b6 v6 S1 b8 b
  27. }
    & ?6 s- H6 a$ ]; v0 A
  28. }
复制代码

$ W' F. G6 m% E9 P% kSector_Test.c 如下:
9 {' O5 j- i; Q. @- Y+ |
  1. #include "stm32f4xx.h"
    0 f+ F& g  U( d6 i$ B
  2. #pragma location = ".CODE_Flash"
    : Z: a; L, u' a8 Y1 f9 W
  3. void Light_Toggle(void)
    ; N. t  }: ?2 U. w
  4. {
    " B7 `5 |9 G* z' N! c
  5. GPIOG->BSRRH = GPIO_Pin_6 | GPIO_Pin_7;& A  {1 i0 \- ^9 S* ~' _% k6 `
  6. }
复制代码

0 `* T6 X" ^8 T2 q4 L0 M' U; W: m; `+ n+ l2 ~
收藏 评论0 发布时间:2022-2-27 16:13

举报

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