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

【NUCLEO-L476RG】IAR flash loader 下载流程简要分析

[复制链接]
andey 发布时间:2022-12-31 12:51
1.IAR 下载配置( e3 t+ T. r2 W% _% \
本次使用的硬件环境为MUCLEO-L476开发板,官方下载的软件包中打开IAR的工程文件,IAR的下载配置如下:
IAR_DOWNLOAD.png

$ r% F) h4 {% {  G
默认配置是使用IAR 系统默认配置文件,我们勾选上Oveerride default .board file文件。
IAR_OVERRIDE.png
. {1 u8 K. l* e1 ]* M0 M  Z
从下载配置中看IAR环境下载使用的是flash loader 进行下载,使用的配置文件为   IAR  安装路径下的此文件$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxG.board
官方的帮助文档中对flash loader 的描述如下,从如下描述中可知,flash loader 是运行在目标系统(MUCLEO-L476开发板)的一段实现特定flash 操作的接口函数集合,IAR 通过C-SPY将flash loader 加载到目标系统(MUCLEO-L476开发板)RAM中运行,完成目标falsh 的更新任务。
  b0 @* o- B# N4 V# I1 ?: A
The flash loader
# P6 n  [5 i: L4 A) VA flash loader is usually a rather small program which can program one or more flash memories.
0 `1 H; K+ _1 O, R7 Z" B3 T3 ?The flash loader consists of a small set of functions, mainly for erasing or writing designated$ q: n( O( [$ l; M: k: h! E+ P4 L
portions of the flash memory. C-SPY downloads this program into RAM (it must be linked to an
7 L! B* h$ A! @6 ]  t* P2 kaddress in RAM). To run the program, C-SPY sets the PC to one of the functions in the flash
) g! ?. @% e1 V" L) G9 sloader, writes data and directives for that function into a RAM buffer, and starts execution.
# M1 ]( q; H% m1 |3 a" g7 o- c! R# W9 CWhen the function returns, execution will hit a breakpoint. C-SPY will then know that the- S& D2 f2 e' D; X
function has finished and can proceed to make further

: d6 e2 o# z! w& l0 k/ `
从如下图片能更清晰的看出flash loader 的工作流程:
, P  Z1 s1 v3 `+ Z9 L4 o
flah_load.png
  • 通过 C-SPY 将 flash loader 程序加载到目标系统预留的RAM区域。
  • 通过 C-SPY 将需要下载测程序加载到目标系统预留的RAM区域,如果可执行程序比较大预留的RAM空间可能不能一次完全放下可以分割成多次传输。
  • 将 IMAGE 镜像通过 flash loader 将 IMAGE 镜像下载至flash.
  • 镜像下载完成后可以释放预留的RAM空间,至此已经完成下载。
    ! P3 R% |( B5 c5 ?/ T- y
) `: a9 ~; R5 n7 J
2. *.board 文件格式说明
此*.board 配置文件的总入口,*.board 文件是什么文件,从IAR的帮助文档摘出如下说明,.board 文件是flash loader 下载镜像的配置文件被IAR 的C-SPY debug 对象引用。
: T8 T1 M+ ~: ^
Ext.Type of file
# t# M- r; p' o1 J
Output fromInput to
board Configuration file for flash loader Text editor C-SPY

/ J. u1 k1 i; }+ d' Z- k( _6 b
$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxG.board文件内容如下:
  1. <?xml version="1.0" encoding="iso-8859-1"?>
    2 P. `2 Y" L6 }8 `- ]
  2. 8 D  x# J# x1 V& a7 t
  3. <flash_board>+ ?5 I& f9 h& j+ O" C0 q
  4.   <pass>
    % B- \4 ?& x3 D3 |
  5.     <loader>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxG.flash</loader>
    7 q, g2 G) \( B/ j% _& e" G
  6.     <range>CODE 0x08000000 0x080FFFFF</range>
    4 _9 G: k. S; U
  7.   </pass>
    ' T# z8 v% N0 z
  8. </flash_board>
复制代码
# q% y/ g( Y/ k# y- s+ u' l: g
从如上xml 的配置指定了,flash 的配置说明及FLASH的范围:
( x9 t% x- C* Q4 @
3. *.flash 文件格式说明
从配置选项可以看出,此.board主要的配置信息是告诉flash loader 要根据Flash STM32L4xxxG.flash 文件的配置下载镜像,此.flash 的文件是什么文件呢,从iar 的文件说明可知,.flash 文件也是C-SPY加载的文件,主要定义了flash 的相关属性配置。

( \/ ^1 @; A2 d3 H5 ]) D( u( \
Ext. Type of file Output from Input to
flash Configuration file for flash loader Text editor C-SPY
4 b" |7 J3 G" b" Z/ O7 f5 T
  1. <?xml version="1.0" encoding="iso-8859-1"?>
    $ \; t* K& _7 R

  2. ) O) `& Y. Z) ]$ T" o
  3. <flash_device>
    $ x# s7 J; S0 T  ?! x
  4.   <exe>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxRAM48K_DUALBANK.out</exe>
    9 B5 K( C! e+ I. a2 H2 a9 w/ f
  5.   <page>8</page>7 P2 b4 `- D3 j8 F0 w
  6.   <block>512 0x800</block>
    ) A4 N% G$ K- t- c; ?' y; X
  7.   <flash_base>0x08000000</flash_base>
    + }8 s7 I. }: a; H# B) q
  8.   <macro>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxx.mac</macro>( u# x; n8 _8 y: T5 ^% c+ E+ O
  9.   <online>1</online>) M, k& y! @2 U; j1 [) X
  10.   <aggregate>1</aggregate>  
    ) g6 G' C) T$ D& i' V/ k
  11.   <args_doc>"--skip_erase" -Don't erase blocks that read empty.</args_doc>
    " r2 X8 ^& S" T3 y( `2 @3 g
  12. </flash_device>
复制代码
如下是上述 xml 文件的配置项说明:
To accommodate a large range of different flash memories, C-SPY uses a few concepts which
$ w: z4 I/ G+ }0 ?detail the characteristics of flash memories.# Q1 S, a" m0 F. p3 ~
Page: E9 {8 t) n4 {1 a+ Y( k7 J6 i8 `# I. N  q
A page is the smallest writable unit of the flash memory. Many flash
: o' g- k' b6 u: j/ Z0 U6 O0 ememories cannot write less than for example 128 or 256 bytes in a8 o3 N3 d& S: r2 X' U( }2 M
single write operation. C-SPY will never request the flash loader to write
( A! _; r( S. ?" j* ^7 a0 eanything smaller than a page, and uses padding if necessary to fill out a
" w, D$ N: @$ u- E( U& Npage. Of course, some flash memories have no such restrictions and can
$ U( f6 _/ d5 |specify a page size of 1 byte.
8 J6 y5 r5 b4 Q. W8 h7 v6 }Block' h1 p! I3 Q4 N2 E
A block is the smallest erasable unit of the flash memory. For example,
/ F2 B! n1 T& v; X' C( H$ ja flash memory with a 256-byte page size could still require that flash, @% A  N2 m1 D2 f! y' O# q
memory should be erased in 4-Kbyte chunks. The block size must
* A+ p" m& R( a! f: f; [$ jalways be a multiple of the page size. A flash memory can consist of
; P1 `: n4 A# z# k6 D) B, |  Kseveral blocks of different sizes. It can also lack such restrictions, in5 S# a8 L2 V, d! ^. [; i6 B
which case the block size would be the same as the page size.
5 [7 F! V9 X0 b+ }8 IBase address4 |) ], X) O! l9 Y9 b! q; J
This is the start address of the flash memory, when it is written. Some
7 P- B: d3 Q  Zflash memories are simply memory mapped into a fixed address range7 `7 o6 W  X+ N6 T% o8 T: M
and the base address is then the start of that range. Other flash memories
: E. S( G4 X7 [  |are mapped into different addresses when being programmed and when
7 z; V7 n% Z9 h1 i& Qthe application is later executing. The base address is then the address
' ~2 k' ^2 C. f% A# W4 }where these memories are mapped when being programmed. Yet other
: ~% a4 X+ Q1 ^$ |- @9 |flash memories are not memory mapped at all, but work more like
) @* D! W+ R! |* b  Vexternal disk-like devices. The base address is then simply the preferred
" n# c6 `$ H; O2 |  I5 M$ ]' F3 Maddress to be used for the start of the memory when it is being8 I# y+ {, A1 e! q. z/ b- y' b/ `
programmed.
9 Z  |" O4 y8 J- \0 NFrom the C-SPY perspective, a flash memory starts at a given address and consists of a sequence
# K9 O. F; o( M! K. `7 Qof blocks (possibly of different sizes), each of which consists of a number of pages. The
; A; E; S" O; z% msequence can also contain gaps.

+ M% H, |" b/ H" \, m2 {3 I$ Q% y
从上述配置文件解析:
STM32L476 的 page 为8byte,共有512 个block 每个  block 大小为2k,总大小为1M,base 地址为0x0800 0000。
flash_page.png

; m, A3 ^4 R/ \' y7 x# G0 l
FLASH main features0 l- E3 S0 M: W" C( @& ~
• Up to 1 Mbyte of Flash memory with dual bank architecture supporting read-while-write5 l: e3 y1 b; W$ f
capability (RWW).2 N7 Z+ j9 P5 F; U8 x# H8 ^6 u
• Memory organization: 2 banks (Bank 1 and Bank 2)
, s, Z1 z( s8 Q0 B– main memory: 512 Kbyte per bank: K  r5 ~" ?* w5 g: ]9 F' d
– information block: 32 Kbyte per bank+ G" Y' X( V8 X- E- K, ]
• 72-bit wide data read (64 bits plus 8 ECC bits)
% |# A3 b% c  i7 S" e$ u• 72-bit wide data write (64 bits plus 8 ECC bits)- C5 \% i5 B# N  g, _/ l
• Page erase (2 Kbyte), bank erase and mass erase (both banks)
4 c) n0 w& E5 Y7 J9 M
从上述描述可以看出flash 的最小读写单位是64bit 8bit ECC,最小的编程单位是8byte,每个最小擦除单位为2kbyte,xml 配置和芯片手册里FLASH 的layout 布局是保持一致的。
- H' I" x* i4 P7 Y- J
2 O- I! y$ N; O) k9 h
4. *.mac 文件格式说明
.mac 文件定义了 C-SPY 调用的宏函数,如下宏函数会在 flash loader 的不同阶段调用宏函数。
. M# L/ G% d7 y. Q/ M5 d

9 e5 u; _/ g+ b2 C
Ext. Type of file Output from Input to
mac C-SPY macro definition Text editor C-SPY
macro Specifies the path to a C-SPY macro file, which will be loaded in9 `' a2 o( M! q& b2 j, `
conjunction with downloading the flash loader.
There are three C-SPY
& g& g5 I9 z' hmacro functions that will be called automatically if they are defined in; C1 ~8 x, ^7 T! I: m8 q
this macro file:  U9 h4 `: ]8 p4 Q; B' H
execUserFlashInit is called immediately before loading the flash, }. M1 f$ w; N$ R" ]* `" [( T
loader.# W: r" o; {8 x; y
execUserFlashReset is called immediately after the reset that+ k% k% Z2 s- g% Y, e
follows the loading of the flash loader.
( e  v& H: {: Z$ z: L$ y6 mexecUserFlashExit is called immediately after flash loading has9 x; U0 w! z- u* h' q* b5 c( `
finished, but before the flash loader is unloaded.

. o' F. x- n0 }, ~7 f! v  V
FlashSTM32L4xxx.mac 内容如下:
  1. __var RCC_CFGR;" o' t* v2 g2 L, ~$ k8 v5 S0 @4 _% I5 v
  2. __var RCC_CR;
    , W. i4 e- q* ]+ P3 H
  3. __var RCC_CIR;
    , j  Z3 }& z0 e2 `& v% x$ @" @
  4. __var IWDG_PR;
    6 r; `' q7 S& _: d, a+ V; w
  5. __var IWDG_RLR;& U( r# f0 f' H2 o+ ^
  6. __var FLASH_ACR;  ^9 R' A$ Q+ u0 s+ C6 t6 Y
  7. 9 w! {2 S% O4 x" @: p
  8. execUserFlashInit()
    6 v. c' L3 e) e8 c. J' _
  9. {
    4 z4 p3 R3 i. F8 |( `4 B8 p
  10. __var tmp;: Q- ^- Q* C: r# Q* E. ?. c

  11. + |! Y* w/ q/ j. O. F7 m
  12. __message "Entry execUserFlashInit";: G9 b. c' N6 ]" K# }

  13. + J" D* c9 ^0 }) r0 L: F& k
  14.   //Stop watchdogs when CPU is halted$ Y% p3 q4 [, {4 y; H8 ]  T2 d0 P
  15.   __writeMemory32(__readMemory32(0xE0042008, "Memory") | 0x1800, 0xE0042008, "Memory");
    ( B7 @+ C+ H! W7 W) N+ F/ M9 s
  16. 1 I0 F. d- k' O9 B- P7 K
  17.   //Check if hardware watchdog is enabled
    + Q- ^0 I+ M; V# e6 ?4 q  h
  18.   if(!((1<<16) & __readMemory32(0x40022020,"Memory")))
    5 r3 C) k) b% @8 h* g" l- R
  19.   {
    $ P! c2 B: {; _& s' Z8 x7 I
  20.     // wait PVU reset
    - n" o  Z, J- v7 r
  21.     while(0x3 & __readMemory32(0x4000300C,"Memory"));
    + X$ X- |9 @. E8 b6 ]+ ?
  22.     IWDG_PR  = __readMemory32(0x40003004, "Memory");$ s; y; ?: _' W0 u8 \4 a& n* |9 {
  23.     IWDG_RLR = __readMemory32(0x40003008, "Memory");  W4 ~4 v9 c) i
  24.   3 T- x/ X' R" w3 e
  25.     // unlock WDT registers
    % U+ c; g: j# G' w/ z
  26.     __writeMemory32(0x5555,0x40003000,"Memory");+ t+ }- }" ~. N; v
  27.     // Prescaler  e/ G# N4 a" H; X/ f. D
  28.     __writeMemory32(0x7,0x40003004,"Memory");. x& o8 J2 y1 D+ `
  29.     // Reload
    ; v5 i: M: V( A9 ^3 b& X4 E
  30.     __writeMemory32(0xFFF,0x40003008,"Memory");: d, W- p4 F9 T9 X! O1 }
  31.     // reload WDT4 e* Q. I- T& e
  32.     __writeMemory32(0xAAAA,0x40003000,"Memory");+ Q5 z  z6 a( N0 W% C
  33.   }" V" t9 G/ q; A! I

  34. ) ^: m2 o  m- `* v% I# |
  35.   RCC_CR   = __readMemory32(0x40021000, "Memory");0 j' O. x2 f. U0 e* f- R
  36.   RCC_CFGR = __readMemory32(0x40021008, "Memory");
    3 ]  o5 _$ @4 N. v+ m- e) ~7 c
  37.   RCC_CIR  = __readMemory32(0x40021018, "Memory");9 }* o6 j- k- N6 t
  38.   
    $ {; m( s$ E, ^; r/ u
  39.   /*Enable HSI16 oscilator and select it as system clock*/# V% F; U+ ^# M0 }
  40.   __writeMemory32(0x00000000, 0x40021018, "Memory");             // RCC_CIR  = 0;
      V! i& p# F2 F$ [9 c4 t
  41.   __writeMemory32(RCC_CR | (1<<8), 0x40021000, "Memory");   // RCC_CR_HSION  = 1;+ F1 L* l- v; i  C
  42.   while(!((1<<10) & __readMemory32(0x40021000,"Memory")));( b# k0 `( t( B- y  u
  43.   tmp = (RCC_CFGR & ~(3<<0)) | (1<<0);4 m' ^0 y( R1 U1 s* c
  44.   __writeMemory32(tmp, 0x40021008, "Memory");                                 // RCC_CFGR_SW  = 1;
    . v/ }4 G. `8 a( x7 Z) g  H
  45.   
    $ J' [+ o7 R2 F- A5 f- a/ _
  46.   FLASH_ACR = __readMemory32(0x40022000, "Memory");6 H% ^7 }1 c$ ^6 @8 N1 t
  47.   tmp = (FLASH_ACR & ~(0x7<<0)) | (2<<0);# H2 E+ x% O5 E. O5 V
  48.   tmp &= ~(3<<9);$ v6 N6 J. }. N7 `
  49.   __writeMemory32(tmp, 0x40022000, "Memory"); // 2 WS (3 CPU cycles) & disable caches" A$ r: {4 A; i7 A' |' s
  50.   tmp |= (3<<11);
    1 l# d  E& d/ ^7 e* c- T* s
  51.   __writeMemory32(tmp, 0x40022000, "Memory"); // reset caches0 K3 o1 a! R1 C* j2 `3 @
  52.   # ^' I, }9 ~: i( T5 R7 w( T
  53.   if ((0xFF & __readMemory32(0x40022020,"Memory")) != 0xAA)2 \- |0 R0 t! M, {9 v
  54.   {
      F/ f$ L& V  _+ p
  55.    
    / r: Y. f1 c% X, [* ]
  56.     if (!__messageBoxYesCancel("Do you want to perform mass erase to unlock the device?", "Unlocking device"))- [: B! K+ B/ I6 }& h; y; a
  57.     {7 o, |" o- D! r$ L& b0 Z. f
  58.       __abortLaunch("Unlock cancelled. Debug session cannot continue.");& C" v, T  H4 D
  59.     }6 J- V- ?  z/ t  k2 k9 q: u

  60. : g/ A. b' y! n
  61.     __writeMemory32(0x45670123, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY1;: f* F1 x$ A4 F: E: U
  62.     __writeMemory32(0xCDEF89AB, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY2;/ X, g  q9 P1 M* x& w
  63. //    __writeMemory32(0x00000000, 0x40022000, "Memory"); // Flash 0 wait state
    0 T  d1 h" A$ |+ b( `- w/ y- k' a9 H
  64.     __writeMemory32(0x08192A3B, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY1;) }$ u6 i5 E/ d7 l+ L: O" E
  65.     __writeMemory32(0x4C5D6E7F, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY2; - M) g; _+ a' m; k, Q2 g
  66.       
    , {+ b# m$ H! A# j
  67.     __message "Setting FLASH readout protection level 0 (disabled)";
    $ N: }6 Y* B+ L# Y1 o8 J
  68.   : v  B( b% t* H# g4 f, P/ ]- l8 G
  69.     __writeMemory32((__readMemory32(0x40022020,"Memory") & 0xFFFFFF00) | 0xAA, 0x40022020, "Memory");     // Disable readout protection
    ( O! m) m4 K% C" O& C5 j
  70.    
    * C( ~1 z+ E) b: _: J1 F
  71.     * H$ s9 g  v1 p0 ]) n4 ~
  72.     __writeMemory32((1<<17) | __readMemory32(0x40022014,"Memory"), 0x40022014, "Memory");                 // Set the Options Start bit OPTSTRT
    ' V* r$ m4 I8 ]: B9 \4 v. h

  73. 4 E# a0 E0 j5 A5 Z" |8 ~% h) Q% f# E
  74.     while((1<<16) & __readMemory32(0x40022010,"Memory"));  // Wait while FLASH busy/ _  O0 k$ y2 \4 _4 X  p3 a
  75.         
    1 w+ D. q  H& v, g+ j3 v
  76.     __writeMemory32((1<<27) | __readMemory32(0x40022014,"Memory"), 0x40022014, "Memory");                 // Set the OBL_LAUNCH to Force the option byte loading4 |, q: X# p5 K+ o5 c- [
  77.       
    % W) p/ A3 a* k+ g6 `" A3 g4 m* L
  78.   }. t+ T8 W8 D# m) u
  79. }
    ( L. V3 g9 }; d# i/ y$ t

  80. 6 F7 ?& A  W% {( X; r
  81. execUserFlashExit()
    2 c, N; N2 e; ^3 s, Z
  82. {
    " q. h8 z# W9 o4 v. m* U7 D
  83. __message "Entry execUserFlashExit";
    / T" E. A4 a9 [- \7 l0 p
  84.   if(!((1<<16) & __readMemory32(0x40022020,"Memory")))5 O& {1 b5 q, F4 A) I
  85.   {! F, x) ~; q1 ~; O" e; F
  86.     __writeMemory32(0x5555,0x40003000,"Memory");- q5 B9 J  S" e- @7 b; g* e
  87.     __writeMemory32(IWDG_PR,0x40003004,"Memory");
    3 C* n% N, V& x% e1 ]/ c7 f
  88.     __writeMemory32(IWDG_RLR,0x40003008,"Memory");( x, l3 \4 K% W6 d/ L/ z
  89.     __writeMemory32(0xAAAA,0x40003000,"Memory");. z( q1 p9 R! Z  c. \) J
  90.   }/ g  T9 f5 D/ c- Y( n

  91. 3 ^; G6 R' v) [( M8 m- _' b5 [0 s: c: ?
  92.   //Restore registers modified earlier: R/ d+ X$ R1 C, F$ I9 p) `- G8 g0 ^
  93.   __writeMemory32(RCC_CFGR, 0x40021008, "Memory");% r, B+ p5 Y- L. ]0 U1 m" C
  94.   __writeMemory32(RCC_CR, 0x40021000, "Memory");& F) r$ }1 B  z+ O' f
  95.   __writeMemory32(RCC_CIR, 0x40021018, "Memory");% K( Y2 v2 P8 q! H8 F1 V
  96. 9 g( n& N- H' u9 ~% F! [" U
  97.   __writeMemory32(FLASH_ACR, 0x40022000, "Memory");
    ! R! }8 h- A8 ^- H# l, t: k. I. b
  98. }
复制代码
7 s% M+ I/ t6 a- K. k! u
从上述.mac 文件中定义了如下宏函数,并在入口中添加了打印输出:

+ N' n; @4 m7 p: Y% n& K
execUserFlashInit()
$ g6 G) G$ ]/ X1 ~- }
execUserFlashExit()

, j: o" n' e& s9 t$ y4 c5 Y; @( p
; F" o1 I7 s9 s2 e9 _
5.下载验证
5 ]- ~+ ^5 k5 D5 ?/ o, @
macros 文件是可以被C-SPY 调用的执行文件,为了验证个人的猜想在execUserFlashInit 入口和出口追加了log 输出,来确认猜测是否正确。/ e$ t) v9 ~% s: \( z
有了上述的配置信息及flash 的初始化处理,flash loader程序就可以吧编译的二进制下载到板子上执行了。准备下环境验证下上述猜测是否正确。
! \1 J$ a" l7 l' u
debug_loader.png
, x" v6 x0 b# ~, M
. T& y2 y& u/ X& ?$ ?
从debug log 窗口可以发现mac 文件内定义的函数入口打印输出跟预期的是一致的,同时从log 个中也可以看出flash loader(FlashSTM32L4xxxRAM48K_DUALBANK.out) 程序是按照上述描述的方式被C-SPY 加载到目标系统。
' W- p; s5 G. p; t4 y
  1. Flash loader example
    . m) z- z9 I; S- l$ H, D
  2. The following example shows the source code for a complete flash loader (except the source+ v  F* b9 K9 X# N8 X0 @8 ^
  3. code for the framework), but with a flash programming algorithm which simply copies bytes
    ) x( [# x/ q! N1 r* V) l$ x. `
  4. from the RAM buffer to the destination address:5 f! b4 E2 F* \3 O* W2 h% D6 I
  5. #include "flash_loader.h"
    - w* W8 M, q; ~+ D7 c5 @9 v9 _
  6. uint32_t FlashInit(void *base_of_flash, uint32_t image_size,' B4 {/ s2 C" ~3 |1 I+ b
  7. uint32_t link_address, uint32_t flags)
    1 \$ X2 q7 b+ M! b7 Y* W
  8. {. m5 B. [/ F1 d/ h, c  u( \- N; Z: j6 \3 o
  9. return RESULT_OK;
    7 |( ^  j5 [! g
  10. }$ C7 x6 p, z2 z4 n" g
  11. uint32_t FlashWrite(void *block_start,
    0 l' Q3 u! P1 D" S
  12. uint32_t offset_into_block,' P: q' m5 @1 x8 x- X% _) o
  13. uint32_t count,9 D- a# `6 a% ?5 X/ T- Q; S
  14. char const *buffer)
    2 J, G% w. h2 D1 O0 e4 x
  15. {
    8 c& r, ]% M+ X+ y! ^" a
  16. char *to = (char*)block_start + offset_into_block;
    # z1 P4 R( J6 v9 X  l% r& I
  17. while (count--)
    ' X( E+ B( P+ {& _# z
  18. {+ ]* V5 g- n: @# p9 {
  19. *to++ = *buffer++;) [; r9 `+ f% i) |, \2 H  e* H2 z
  20. }5 p7 i9 @. c8 p
  21. return RESULT_OK;
    5 ^3 e: Z8 v0 w# x2 H* K/ c
  22. }
    ! ]9 Y" m6 P8 P% J
  23. uint32_t FlashErase(void *block_start, uint32_t block_size)
    3 v( t) O0 J( O9 O+ v: y
  24. {
    + L, v" K& m% W$ [2 b
  25. char *p = (char*)block_start;) E2 e$ H! k4 x5 u
  26. while (block_size--)4 M* w6 |; i; m2 l+ A8 N
  27. {
    . g/ S2 L2 T/ y0 N, A7 T
  28. *p++ = 0;4 Z9 j& W9 A4 q
  29. }
    ; [; j* S2 t+ p/ y0 }# n8 m# y" v# l
  30. return RESULT_OK;: @4 O8 D3 b% O; n3 E. O8 q
  31. }# n: `. Y$ Q# y6 X' h% Z5 _+ V
  32. The parameters to FlashWrite and FlashErase, in combination with the flash memory base' e$ q2 G) ?' I/ J
  33. address given in FlashInit, fully specify the addresses of the portions of the flash memory to
    # p$ M" F1 C2 K/ \2 a5 `
  34. be programmed. Thus, a given flash loader can be used for any number of different flash% _  v1 K$ q! m3 ~& e: Y
  35. devices, with different total size, page size, or block layout, provided that they all employ the" d7 p  i! O8 `1 N& @+ Z2 H, u
  36. same flash programming algorithm. The flash memory configuration file (.flash) is used for
    % ^& _( q# C- K: r9 I: Q! B
  37. specifying such variations between flash memories.6 U$ N2 x# a# {6 |; N
  38. The reference section at the end of this document describes all framework functions in detail.
复制代码
5 _( _7 _6 y1 Q) _6 i$ C$ I: n
从上述flash loader 的示例程序中实现了FlashInit/FlashWrite/FlashErase 三个api 函数,我们可以objdump 下flash loader 程序看下内部是否是按照上述方式实现了对应的接口。

! t0 j5 @. V% a+ F* o
  1.                 FlashInit:% F) j+ z1 y8 ]  ?
  2.   0x200000c4: 0xb510         PUSH   {R4, LR}: @# p6 q( g2 e/ ]& Y
  3.   0x200000c6: 0x494a         LDR.N  R1, `.text_8`          ; flash_ie
    & p! s9 x# H) s$ D8 P" ]
  4.   0x200000c8: 0xf500 0x2200  ADD.W  R2, R0, #524288        ; 0x80000- h# P; y" S) \
  5.   0x200000cc: 0x604a         STR    R2, [R1, #0x4]1 L: m7 ^; I9 F
  6.   0x200000ce: 0x2300         MOVS   R3, #0: }6 S" t! m0 b4 Y1 V+ X- D
  7.   0x200000d0: 0x2200         MOVS   R2, #0
    ; N9 X$ L+ ], B
  8.   0x200000d2: 0x700a         STRB   R2, [R1]3 O: \! I0 }* \2 g
  9.   0x200000d4: 0x9a02         LDR    R2, [SP, #0x8]
    % b2 O! j) \; }) [" n
  10.   0x200000d6: 0xe000         B.N    @200000da
    ' v3 h  D* a' ?  ?
  11.                 @200000d8:
    ) `, X4 A# n: ?5 i$ S( \
  12.   0x200000d8: 0x1c5b         ADDS   R3, R3, #1
    / x% I+ Q4 U8 Q) g/ m3 y
  13.                 @200000da:* w0 Z$ {, Z" ^. X
  14.   0x200000da: 0x4293         CMP    R3, R2
    5 p$ p7 N8 e& D7 a9 H6 s+ ^% t
  15.   0x200000dc: 0xdbfc         BLT.N  @200000d8
    9 s. B$ G9 ~/ ~
  16.   0x200000de: 0x4a45         LDR.N  R2, `.text_9`          ; 0x40022008 (1073881096)
    + M! E" U1 R5 B5 c8 h; e( g
  17.   0x200000e0: 0x6993         LDR    R3, [R2, #0x18]
    9 @5 M$ r6 @& c" S, i
  18.   0x200000e2: 0x029b         LSLS   R3, R3, #100 p: S1 O; O. ^
  19.   0x200000e4: 0xd507         BPL.N  @200000f6
    ; r& Z, ]4 C+ Q/ @
  20.   0x200000e6: 0x4b44         LDR.N  R3, `.text_10`         ; 0x1fff75e0 (536835552)6 j+ h) I( ]# z8 v( Q
  21.   0x200000e8: 0x4c44         LDR.N  R4, `.text_11`         ; 0x3ffc00 (4193280)
    " Z7 [  P2 S; E8 l0 o
  22.   0x200000ea: 0x881b         LDRH   R3, [R3]. h4 g! i! j" v% M* q
  23.   0x200000ec: 0xea04 0x2383  AND.W  R3, R4, R3, LSL #101 c+ h+ C) y* H" G
  24.   0x200000f0: 0xeb00 0x0063  ADD.W  R0, R0, R3, ASR #1$ E: m9 J1 {3 K" z# j; x
  25.   0x200000f4: 0x6048         STR    R0, [R1, #0x4]) p7 G' u& ^& P  l: U: [
  26.                 @200000f6:
    ( s! f. N  G8 f3 }/ [- ^$ Z
  27.   0x200000f6: 0x4842         LDR.N  R0, `.text_12`         ; 0xe000e100 (-536813312)! e: t6 v4 p0 x! X
  28.   0x200000f8: 0x4b42         LDR.N  R3, `.text_13`         ; 0xe000e180 (-536813184)- z( @- E* Z" t0 s; `
  29.   0x200000fa: 0x6800         LDR    R0, [R0]
    8 j) G: t" N) T" w+ C7 c
  30.   0x200000fc: 0x06c0         LSLS   R0, R0, #27
    , j- L0 a4 Q! ^5 r3 i
  31.   0x200000fe: 0xbf44         ITT    MI$ V$ {" L4 D  Y' ]- l- P" j  l
  32.   0x20000100: 0x2001         MOVMI  R0, #1
    ) L* j8 b6 N, q: {" g
  33.   0x20000102: 0x7008         STRBMI R0, [R1]
    7 E: I. G. Z) Q) y& P, X: r1 H
  34.   0x20000104: 0x2010         MOVS   R0, #16                ; 0x10
    5 {3 N2 @8 `" W( x1 e
  35.   0x20000106: 0x6018         STR    R0, [R3]
    4 F$ M3 ^9 N4 H# |2 l* `- m" v* `
  36.   0x20000108: 0x4b3f         LDR.N  R3, `.text_14`         ; 0xc7000ff8 (-956297224); m, s3 c6 H& B4 k
  37.   0x2000010a: 0x68d0         LDR    R0, [R2, #0xc]7 e' @6 {. x# P$ I( e. J
  38.   0x2000010c: 0x4018         ANDS   R0, R0, R3
    ) j7 r$ b8 p% g& B. k8 D
  39.   0x2000010e: 0x6088         STR    R0, [R1, #0x8]
    & R( S! j, f8 T
  40.   0x20000110: 0x483e         LDR.N  R0, `.text_15`         ; 0x45670123 (1164378403)
    / G$ ]) @1 m) ^/ y# [
  41.   0x20000112: 0x6010         STR    R0, [R2]
    3 ?2 X' ~6 F4 W: {$ B
  42.   0x20000114: 0x483e         LDR.N  R0, `.text_16`         ; 0xcdef89ab (-839939669)! ^  b& W* T* B. Q; U, c
  43.   0x20000116: 0x6010         STR    R0, [R2]! B& w+ s" l( l' a
  44.   0x20000118: 0x68d0         LDR    R0, [R2, #0xc]
    - f) F# S1 \6 n/ U: q
  45.   0x2000011a: 0xf020 0x60c0  BIC.W  R0, R0, #100663296     ; 0x6000000
    / D( W! q5 x  r1 q) p
  46.   0x2000011e: 0x60d0         STR    R0, [R2, #0xc], _/ A/ [$ y  b( r# |
  47.   0x20000120: 0x68d0         LDR    R0, [R2, #0xc]
    4 {; f/ V9 `/ Z+ `& h5 M' o
  48.   0x20000122: 0xf040 0x7080  ORR.W  R0, R0, #16777216      ; 0x10000005 \+ d. T7 x: O) v6 ^8 j( y. A# g
  49.   0x20000126: 0x60d0         STR    R0, [R2, #0xc]
    : m! n8 u. C; _
  50.                 @20000128:
      y4 [) e/ \0 P
  51.   0x20000128: 0x6890         LDR    R0, [R2, #0x8]
    ; {; J4 N' R/ }8 Q* Q
  52.   0x2000012a: 0x03c0         LSLS   R0, R0, #152 J" |* `6 M: k2 W% S, K0 b
  53.   0x2000012c: 0xd4fc         BMI.N  @200001284 `$ B! l" l% E2 B0 b
  54.   0x2000012e: 0x2000         MOVS   R0, #0
    * S# Z+ u  L8 w2 i8 ^
  55.   0x20000130: 0xbd10         POP    {R4, PC}, Q# i7 V' U/ R& ^) Y/ e; _' K
  56.                 `.text_5`:% D/ ~& v# U8 |( V# m
  57.                 FlashWrite:  ]1 {) B, Q; A) k/ s- R
  58.   0x20000132: 0xb5f0         PUSH   {R4-R7, LR}0 h2 y0 \& A3 K
  59.   0x20000134: 0xf240 0x15ff  MOVW   R5, #511               ; 0x1ff. ^% z7 L; p3 {+ `* q; g+ h
  60.   0x20000138: 0x1844         ADDS   R4, R0, R1
    9 ~" u' `* X- j5 X7 b
  61.   0x2000013a: 0x4936         LDR.N  R1, `.text_17`         ; 0x40022010 (1073881104)# p* ^/ N. F" Z1 q) l
  62.   0x2000013c: 0x600d         STR    R5, [R1]
    & a* B1 o7 A+ q0 X& c
  63.   0x2000013e: 0x2000         MOVS   R0, #0
    ' p8 Y( I0 {8 b1 {6 M
  64.   0x20000140: 0x684d         LDR    R5, [R1, #0x4]
    $ L- x9 f0 W5 u. `) g& _
  65.   0x20000142: 0xf045 0x0501  ORR.W  R5, R5, #1
    4 f6 g# `+ F7 d  L- e  g
  66.   0x20000146: 0x604d         STR    R5, [R1, #0x4]5 r( e: a' U5 _% h
  67.   0x20000148: 0xe000         B.N    @2000014c
    3 S& X" I; H2 H# p8 Z0 R+ o. t
  68.                 @2000014a:
    ! H* S5 g) u4 V. D
  69.   0x2000014a: 0x3a08         SUBS   R2, R2, #8
    $ C1 |8 x  g6 b, I. U- C
  70.                 @2000014c:) D- D" D  f" ?% U0 X& i, q3 f! X
  71.   0x2000014c: 0xb162         CBZ    R2, @20000168
    / g) B3 O7 ]! ]! \- _8 y+ o
  72.   0x2000014e: 0xe8f3 0x6702  LDRD   R6, R7, [R3], #0x83 E) i: p# w  T4 l2 Y* b$ p
  73.   0x20000152: 0xe8e4 0x6702  STRD   R6, R7, [R4], #0x8+ ^" m3 H1 q5 e
  74.   0x20000156: 0xbf00         NOP
    ' {% G% g, _* m0 {0 V2 s% E( S
  75.   0x20000158: 0xbf00         NOP
    ( @$ S& r% @! ?% M
  76.                 @2000015a:4 H0 Y& u  {( K6 k% J! G+ z  _0 {1 t
  77.   0x2000015a: 0x680d         LDR    R5, [R1]; Q) u7 Q' @$ h' A1 `. W
  78.   0x2000015c: 0x03ed         LSLS   R5, R5, #15# x0 ]3 N/ w& |+ N
  79.   0x2000015e: 0xd4fc         BMI.N  @2000015a
    8 q) W. R. E- b1 b
  80.   0x20000160: 0x680d         LDR    R5, [R1]$ W1 M; @; ~1 Y. ~* N. g7 o
  81.   0x20000162: 0x07ed         LSLS   R5, R5, #31
    * N5 r5 L: J+ g) X0 v6 u6 K
  82.   0x20000164: 0xd4f1         BMI.N  @2000014a
    + [9 \$ C0 n1 i8 B- w. q4 Z
  83.   0x20000166: 0x2001         MOVS   R0, #1
    7 v4 v' E9 [! K7 `8 t9 K4 H5 y
  84.                 @20000168:( t: X, k6 h, h! h7 ], y( k
  85.   0x20000168: 0x684a         LDR    R2, [R1, #0x4]
      l5 R( m1 W9 v* d0 ^* [3 b) I
  86.   0x2000016a: 0x0852         LSRS   R2, R2, #1& t$ b; A0 \, T5 Y9 L- `/ M; m2 u+ r! A
  87.   0x2000016c: 0x0052         LSLS   R2, R2, #12 ^* W% M+ }& O: l0 X
  88.   0x2000016e: 0x604a         STR    R2, [R1, #0x4]0 B- }* `6 O5 s8 T) T! Y5 n
  89.   0x20000170: 0xbdf0         POP    {R4-R7, PC}
    + |2 F* ^+ ^% ?! ^& d+ R; T
  90.                 `.text_6`:7 p$ D9 V8 w  p" J0 ~& Q1 N: w
  91.                 FlashErase:
    8 X* w/ u2 o" I7 @) l) N$ p/ f
  92.   0x20000172: 0x4a28         LDR.N  R2, `.text_17`         ; 0x40022010 (1073881104)& \, e7 V, p5 ]3 Y, g
  93.   0x20000174: 0xf240 0x13ff  MOVW   R3, #511               ; 0x1ff; f+ D" C! F4 G
  94.   0x20000178: 0x6013         STR    R3, [R2]3 ]( l3 i6 t  V, q
  95.   0x2000017a: 0x4601         MOV    R1, R06 `: O9 r$ h9 |; Z
  96.   0x2000017c: 0x6853         LDR    R3, [R2, #0x4]
    3 o+ h2 z* h4 O$ w" f' t  s8 d( v
  97.   0x2000017e: 0xf36f 0x03cb  BFC    R3, #3, #9
    / t, _3 L+ b9 n# E2 j
  98.   0x20000182: 0x6053         STR    R3, [R2, #0x4]5 L, _5 }( ~0 t
  99.   0x20000184: 0x2000         MOVS   R0, #0' i- i. f) i' ]5 S
  100.   0x20000186: 0x4b1a         LDR.N  R3, `.text_8`          ; flash_ie5 Q' W  E. v5 @/ C; H
  101.   0x20000188: 0x685b         LDR    R3, [R3, #0x4]9 G, N2 P/ g! v5 `* ]( h! a
  102.   0x2000018a: 0x4299         CMP    R1, R3
    5 M: ^  ~% W& o* B+ }
  103.   0x2000018c: 0xd203         BCS.N  @200001962 w# F3 O: X* H
  104.   0x2000018e: 0x0a09         LSRS   R1, R1, #8' y, R1 |, \$ e' C- N$ n
  105.   0x20000190: 0xf401 0x61ff  AND.W  R1, R1, #2040          ; 0x7f86 ^, V& w1 M; K$ R2 e8 d. L
  106.   0x20000194: 0xe007         B.N    @200001a6
    ! ?- r/ s. y0 \; X& O
  107.                 @20000196:
    8 g4 n3 F0 u5 f" h" u. K
  108.   0x20000196: 0x1ac9         SUBS   R1, R1, R38 d+ s, k# A: H
  109.   0x20000198: 0x6853         LDR    R3, [R2, #0x4]' L. t* ]) P: K
  110.   0x2000019a: 0x0a09         LSRS   R1, R1, #85 Q9 N4 u, Q6 ^, B; u
  111.   0x2000019c: 0xf443 0x6300  ORR.W  R3, R3, #2048          ; 0x800
    ( |! k3 h. W. E8 ]) ?5 v
  112.   0x200001a0: 0xf401 0x61ff  AND.W  R1, R1, #2040          ; 0x7f8
    * `) ?2 r0 ?3 J( X5 B8 P
  113.   0x200001a4: 0x6053         STR    R3, [R2, #0x4]
    6 N( G1 F, w8 F6 }( \0 Y+ Z* Z
  114.                 @200001a6:
    9 D/ p. \- e0 U) e' l1 J
  115.   0x200001a6: 0xf041 0x0102  ORR.W  R1, R1, #2* }9 x7 x8 Q* `, c1 M3 {/ W( C2 `
  116.   0x200001aa: 0x6853         LDR    R3, [R2, #0x4]
    0 |7 o0 w& A$ K9 P. [
  117.   0x200001ac: 0x4319         ORRS   R1, R1, R3
    0 l% g7 B  P: g3 o. A/ U+ |
  118.   0x200001ae: 0x6051         STR    R1, [R2, #0x4]4 u: i6 p+ f- j* S
  119.   0x200001b0: 0x6851         LDR    R1, [R2, #0x4]
    8 i0 h5 l" m5 p. I
  120.   0x200001b2: 0xf441 0x3180  ORR.W  R1, R1, #65536         ; 0x10000% C% \9 R+ I# ^/ f. J
  121.   0x200001b6: 0x6051         STR    R1, [R2, #0x4]
    ( z; V9 r+ C2 Z$ @9 g
  122.   0x200001b8: 0xbf00         NOP" ]5 U, m. a: Z" o, C3 i, _
  123.   0x200001ba: 0xbf00         NOP) G8 N; u) S5 A
  124.                 @200001bc:' c1 w7 O! |% h  x: ~' u
  125.   0x200001bc: 0x6811         LDR    R1, [R2]
    1 k! v( d" V* D* F5 `7 P, p7 K
  126.   0x200001be: 0x03c9         LSLS   R1, R1, #15
    / v, R  }& r8 B2 _
  127.   0x200001c0: 0xd4fc         BMI.N  @200001bc* T3 l" W2 y* R* g! w% ~' \  }4 `
  128.   0x200001c2: 0x6811         LDR    R1, [R2]' K6 [, ~" E0 u+ O6 {- c
  129.   0x200001c4: 0x07c9         LSLS   R1, R1, #31
    ! A. t% V9 B( H+ h
  130.   0x200001c6: 0x6851         LDR    R1, [R2, #0x4]
    1 p+ }" g0 {; x, t1 I  P( e
  131.   0x200001c8: 0xf021 0x0102  BIC.W  R1, R1, #2* t  @; Q3 ]2 j* q9 b9 f
  132.   0x200001cc: 0xbf58         IT     PL3 n. y$ N. R- I) x- i
  133.   0x200001ce: 0x2001         MOVPL  R0, #18 |) j9 M- J5 H
  134.   0x200001d0: 0x6051         STR    R1, [R2, #0x4]
    $ J/ H8 |+ R' ]& P+ ?$ E! H
  135.   0x200001d2: 0x4770         BX     LR
复制代码

* q3 ^# ~7 r/ e3 H7 z1 i
上述通过  
ielfdumparm.exe  FlashSTM32L4xxxRAM48K_DUALBANK.out  -o FlashSTM32L4xxxRAM48K_DUALBANK.ASM --code
命令dump 出来的flash loader 程序,跟预期的保持一致实现了FlashInit/FlashWrite/FlashErase 这组API函数,而且通过反汇编的函数地址信息也可以看出对应的函数的link 地址并不是falsh 区域而是内部RAM 的地址,跟C-SPY 调用flash loader 程序的流程是一致的。
& i5 A5 u# ^* h3 [
; ^/ D/ X! _7 i% t. v
资料分割线
FlashLoaderGuide.ENU.pdf (233.17 KB, 下载次数: 8)
赞 收藏 评论0 发布时间:2022-12-31 12:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版