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

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

[复制链接]
andey 发布时间:2022-12-31 12:51
1.IAR 下载配置
1 j4 u9 |+ _$ q3 W5 ^& Z4 W本次使用的硬件环境为MUCLEO-L476开发板,官方下载的软件包中打开IAR的工程文件,IAR的下载配置如下:
IAR_DOWNLOAD.png
8 D4 @8 w: P/ t! J3 R* i
默认配置是使用IAR 系统默认配置文件,我们勾选上Oveerride default .board file文件。
IAR_OVERRIDE.png

( b- ]& n4 J  L  L! _
从下载配置中看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 的更新任务。
3 c8 b9 w  E" L7 ~& q/ }
The flash loader) T" b6 o! `3 S! Y; T
A flash loader is usually a rather small program which can program one or more flash memories.; L( j0 m0 j3 U- e$ o* R2 S
The flash loader consists of a small set of functions, mainly for erasing or writing designated
, B2 u; U4 \& _5 yportions of the flash memory. C-SPY downloads this program into RAM (it must be linked to an" h0 q, b' e1 Q
address in RAM). To run the program, C-SPY sets the PC to one of the functions in the flash
4 ?! c  d% \) g- ~loader, writes data and directives for that function into a RAM buffer, and starts execution.
. Y5 s  f3 q, b6 p+ f8 h" @When the function returns, execution will hit a breakpoint. C-SPY will then know that the% k$ _+ X$ B; D% p6 Y
function has finished and can proceed to make further
  K+ L6 m+ Y2 D9 B/ {
从如下图片能更清晰的看出flash loader 的工作流程:

2 B" O& A5 N$ V3 _  Z% \$ h
flah_load.png
  • 通过 C-SPY 将 flash loader 程序加载到目标系统预留的RAM区域。
  • 通过 C-SPY 将需要下载测程序加载到目标系统预留的RAM区域,如果可执行程序比较大预留的RAM空间可能不能一次完全放下可以分割成多次传输。
  • 将 IMAGE 镜像通过 flash loader 将 IMAGE 镜像下载至flash.
  • 镜像下载完成后可以释放预留的RAM空间,至此已经完成下载。
    6 F( z- n0 w! R
+ B$ d( k& _" w4 {* S& I' [) s3 a
2. *.board 文件格式说明
此*.board 配置文件的总入口,*.board 文件是什么文件,从IAR的帮助文档摘出如下说明,.board 文件是flash loader 下载镜像的配置文件被IAR 的C-SPY debug 对象引用。
" x) e4 a7 U: s, j7 S7 K
Ext.Type of file" s" t9 ?# S& E. p, `
Output fromInput to
board Configuration file for flash loader Text editor C-SPY

$ G) u2 t/ l6 E0 e+ v
$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxG.board文件内容如下:
  1. <?xml version="1.0" encoding="iso-8859-1"?>2 a0 J, s3 ]9 v
  2. : a/ w& Y4 Q6 g0 [
  3. <flash_board>( \8 m* k5 @& N+ J0 L. `0 r
  4.   <pass>
    # X. t# c, W% n; V+ k. t
  5.     <loader>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxG.flash</loader>& a  H: ?: G" N0 O
  6.     <range>CODE 0x08000000 0x080FFFFF</range>
    , `  i( u' b" b! |  h: _
  7.   </pass>
    : D9 w! K0 x$ P; g  P
  8. </flash_board>
复制代码

/ S& K6 X) x7 {+ Y2 l: P. m
从如上xml 的配置指定了,flash 的配置说明及FLASH的范围:
5 T6 q8 j2 z8 v' X) m' n
3. *.flash 文件格式说明
从配置选项可以看出,此.board主要的配置信息是告诉flash loader 要根据Flash STM32L4xxxG.flash 文件的配置下载镜像,此.flash 的文件是什么文件呢,从iar 的文件说明可知,.flash 文件也是C-SPY加载的文件,主要定义了flash 的相关属性配置。
- p, F; n  E3 u$ e4 ]& V3 X* E
Ext. Type of file Output from Input to
flash Configuration file for flash loader Text editor C-SPY
3 @% G+ [' k# w3 ?
  1. <?xml version="1.0" encoding="iso-8859-1"?>& v' ]0 Q- w$ ?; r" m- X1 g, z
  2. 8 w: i9 _7 Z3 P" A
  3. <flash_device>) r1 u! y4 z: r/ Y
  4.   <exe>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxRAM48K_DUALBANK.out</exe>
    % ?# g6 O6 z; l+ U! b7 I' J+ q
  5.   <page>8</page>
    5 m5 n+ Z& H' |7 f# u1 F' ?* B
  6.   <block>512 0x800</block>) e1 P+ @/ \5 I6 @: m6 b
  7.   <flash_base>0x08000000</flash_base>
    - V/ u+ k7 T. Q2 B  @5 }' E
  8.   <macro>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxx.mac</macro>5 H( u! d9 e* o. R4 J. B8 E4 w
  9.   <online>1</online>
    & T) l! A: y; v6 [
  10.   <aggregate>1</aggregate>  $ l, }1 R, @8 e1 X9 Y0 U  k* I
  11.   <args_doc>"--skip_erase" -Don't erase blocks that read empty.</args_doc>6 B, v  a3 U- e( o5 x4 T5 L* r
  12. </flash_device>
复制代码
如下是上述 xml 文件的配置项说明:
To accommodate a large range of different flash memories, C-SPY uses a few concepts which8 o" B- ?( |1 v
detail the characteristics of flash memories.
/ ]8 ~% _8 D/ u  L* s7 N. g! u8 _1 [Page
: G1 ?& ]0 D% rA page is the smallest writable unit of the flash memory. Many flash
: W7 \( |, W4 T' dmemories cannot write less than for example 128 or 256 bytes in a
: j7 b; t( S* z! K& Y1 ysingle write operation. C-SPY will never request the flash loader to write
2 @8 d& w1 a8 [( lanything smaller than a page, and uses padding if necessary to fill out a! @0 i$ g# U4 X8 ^
page. Of course, some flash memories have no such restrictions and can
; Y: H( b+ z9 \% W% qspecify a page size of 1 byte.; b1 G- I1 ^( {
Block
% ?1 x3 i, `! W  N! v4 V0 x# [6 @A block is the smallest erasable unit of the flash memory. For example,( K, P$ S3 r- @- d9 `5 J  P
a flash memory with a 256-byte page size could still require that flash- g( M) |0 p) t- e0 K
memory should be erased in 4-Kbyte chunks. The block size must+ E8 j0 W/ Y+ ]' g3 g; n+ v$ U
always be a multiple of the page size. A flash memory can consist of
7 C0 ]8 d# W7 C1 I5 r( ?1 Xseveral blocks of different sizes. It can also lack such restrictions, in, h+ Q+ `: c) O
which case the block size would be the same as the page size.0 b. M1 }9 _9 @% Y3 I. R% t- J
Base address
6 G& Y2 Q2 `/ `4 W7 r. [0 NThis is the start address of the flash memory, when it is written. Some
/ R% e. }  i% J- N5 bflash memories are simply memory mapped into a fixed address range
% l' `1 Y3 F* D- a+ C, f$ Wand the base address is then the start of that range. Other flash memories
/ g" e8 f6 L0 nare mapped into different addresses when being programmed and when& R5 a, x7 G. V# b
the application is later executing. The base address is then the address
1 m' q6 Z  j- L! [9 Cwhere these memories are mapped when being programmed. Yet other& p8 E) s- H1 K( c% L/ v8 d5 R
flash memories are not memory mapped at all, but work more like  h5 q5 v: s* I' O' G- G! g+ Z
external disk-like devices. The base address is then simply the preferred3 x: @" u: H6 R& p  J+ z) K/ O: a
address to be used for the start of the memory when it is being- e6 a2 [8 z  n
programmed.
+ c( f7 n5 K9 ]* nFrom the C-SPY perspective, a flash memory starts at a given address and consists of a sequence
5 C1 k0 `& b; Y8 k3 xof blocks (possibly of different sizes), each of which consists of a number of pages. The9 [3 Y9 ^1 E$ m
sequence can also contain gaps.

7 J8 Z& A. J$ H7 _  G- [
从上述配置文件解析:
STM32L476 的 page 为8byte,共有512 个block 每个  block 大小为2k,总大小为1M,base 地址为0x0800 0000。
flash_page.png
4 k2 ^3 |, u5 c2 F$ S
FLASH main features( g. W/ I& W' j* N, f5 g( ?0 a- Q
• Up to 1 Mbyte of Flash memory with dual bank architecture supporting read-while-write8 f, B  _! l# O  X
capability (RWW).
: T. O3 h7 V. E& \# [  D• Memory organization: 2 banks (Bank 1 and Bank 2)4 Q2 b$ V) e# Q/ f3 {) o7 X
– main memory: 512 Kbyte per bank
( A& j6 y  o, `" @– information block: 32 Kbyte per bank
! z7 w  ~/ d+ |+ N. g% W3 X3 F• 72-bit wide data read (64 bits plus 8 ECC bits)3 C2 Y  C; b) F0 h
• 72-bit wide data write (64 bits plus 8 ECC bits). y9 P/ h' b$ {0 {7 r/ D$ g3 \& s
• Page erase (2 Kbyte), bank erase and mass erase (both banks)
6 Q5 [& l2 y2 n( [% h0 s8 O
从上述描述可以看出flash 的最小读写单位是64bit 8bit ECC,最小的编程单位是8byte,每个最小擦除单位为2kbyte,xml 配置和芯片手册里FLASH 的layout 布局是保持一致的。
  P: l( J- Z5 q# c! o! j7 N+ D( ]
* y6 ?2 V& ]5 I2 {5 d. Q$ k
4. *.mac 文件格式说明
.mac 文件定义了 C-SPY 调用的宏函数,如下宏函数会在 flash loader 的不同阶段调用宏函数。
' G" {0 X5 l. A
4 i  @; d3 \- t% A9 T( D! }
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 in0 {2 E  P/ r5 b: u
conjunction with downloading the flash loader.
There are three C-SPY
' Z1 j: x. V! U' {macro functions that will be called automatically if they are defined in, i# V' m# r6 Z" v6 w
this macro file:
: x) ^3 V- l0 _9 u! _  c8 W0 MexecUserFlashInit is called immediately before loading the flash
4 j% X( F7 W0 p0 k9 X' N2 mloader.
! G) _( S' C# L7 ?execUserFlashReset is called immediately after the reset that
# Q! x/ _7 Q1 f$ s) p1 nfollows the loading of the flash loader.
: y) Y4 ~6 F6 e6 R& {- D6 HexecUserFlashExit is called immediately after flash loading has
/ z* g& o* Z* Vfinished, but before the flash loader is unloaded.

$ Y8 H2 ]3 N9 u* Y( n
FlashSTM32L4xxx.mac 内容如下:
  1. __var RCC_CFGR;
    ' j* E1 ^9 z" v6 m1 n
  2. __var RCC_CR;
    - p$ z( x6 n! N4 ?& N% y3 \
  3. __var RCC_CIR;# `7 |# P0 l% u" q  f
  4. __var IWDG_PR;
    ; L3 {* D$ H  T: L' K& g$ Y
  5. __var IWDG_RLR;
    $ \" i4 t- f' U) S; E% \
  6. __var FLASH_ACR;
    ( W' B; w6 @- s/ h7 i' c5 F9 v& X
  7. ) \7 R% b+ h- V$ o4 m
  8. execUserFlashInit()" m+ f$ o7 O, A7 x5 m, y3 K! k6 `
  9. {
    " L9 l$ E. a1 @' x0 |+ s
  10. __var tmp;
    ( c2 P) e7 v9 e% _

  11. 5 O+ W- `; p  D
  12. __message "Entry execUserFlashInit";
    * ]$ \; C( U8 X, g
  13. , h. |  i, O9 O& T" f
  14.   //Stop watchdogs when CPU is halted
    2 t+ z; [4 C* T" ^& \) O. ~1 x
  15.   __writeMemory32(__readMemory32(0xE0042008, "Memory") | 0x1800, 0xE0042008, "Memory");: }1 S/ M% [* n9 q# G! t
  16. , n" |6 c8 s0 b# p- O
  17.   //Check if hardware watchdog is enabled
    ( N0 |" r. m* E% c; e9 l
  18.   if(!((1<<16) & __readMemory32(0x40022020,"Memory")))
    1 P; a% b) w4 H+ m
  19.   {
    % G- v! c8 U. N2 T: N' B
  20.     // wait PVU reset3 G9 U$ @) X) x" j2 g: ~
  21.     while(0x3 & __readMemory32(0x4000300C,"Memory"));! ^7 P; ~  |) o$ k+ d5 S% q, }3 E0 Y
  22.     IWDG_PR  = __readMemory32(0x40003004, "Memory");2 B2 O" X5 F: {) V- r- z+ F" j
  23.     IWDG_RLR = __readMemory32(0x40003008, "Memory");
    7 ^) Y2 P( A% a$ |
  24.   
      [9 v& ?8 R6 {: a- r% ?
  25.     // unlock WDT registers
    8 Q, |2 K2 X9 c- H8 v9 \* L) a0 n
  26.     __writeMemory32(0x5555,0x40003000,"Memory");
      a" H: j7 E; t$ h/ O- A
  27.     // Prescaler
    , ~; @2 o  ~2 @
  28.     __writeMemory32(0x7,0x40003004,"Memory");
    " `3 z! M, d( q) p
  29.     // Reload7 j# U8 [" ^% a! g4 p( `
  30.     __writeMemory32(0xFFF,0x40003008,"Memory");
    , X5 s- u: G6 t% o
  31.     // reload WDT) i  k- Y' C! C# ]- v$ p! m
  32.     __writeMemory32(0xAAAA,0x40003000,"Memory");
    8 B. }7 o4 {. g0 C* u/ _7 }$ ?; S+ ^
  33.   }, ^% ]( o1 Y' e0 I) M7 E, P+ J

  34. 2 E1 o- j8 i$ i6 G4 h1 `
  35.   RCC_CR   = __readMemory32(0x40021000, "Memory");
    % L# ^7 b& i( z' {9 s
  36.   RCC_CFGR = __readMemory32(0x40021008, "Memory");1 j' k4 {7 x% O7 V( q
  37.   RCC_CIR  = __readMemory32(0x40021018, "Memory");
    3 f5 u3 G& S; G. H+ `) I
  38.   $ u  y2 n( l" c3 V3 L
  39.   /*Enable HSI16 oscilator and select it as system clock*/
      \: ?" w4 T' z" b6 ^
  40.   __writeMemory32(0x00000000, 0x40021018, "Memory");             // RCC_CIR  = 0;
    8 W- B. X4 q! u; v
  41.   __writeMemory32(RCC_CR | (1<<8), 0x40021000, "Memory");   // RCC_CR_HSION  = 1;$ k, S1 |7 o9 J" H7 W% ]
  42.   while(!((1<<10) & __readMemory32(0x40021000,"Memory")));2 Y- L3 \  ?- x* z
  43.   tmp = (RCC_CFGR & ~(3<<0)) | (1<<0);
    ; P3 i' I; M5 H3 H% ^+ i( T
  44.   __writeMemory32(tmp, 0x40021008, "Memory");                                 // RCC_CFGR_SW  = 1;
    ( M8 c; O0 Z% ]
  45.   
    / J6 Y/ }% m4 I, }% R0 a
  46.   FLASH_ACR = __readMemory32(0x40022000, "Memory");
    9 K) s$ ~0 [( {7 @
  47.   tmp = (FLASH_ACR & ~(0x7<<0)) | (2<<0);- Y" _- |' Z3 m: w3 u- M2 ]
  48.   tmp &= ~(3<<9);
    * H9 n% p% C, C, @$ G' m
  49.   __writeMemory32(tmp, 0x40022000, "Memory"); // 2 WS (3 CPU cycles) & disable caches
    3 J+ z3 B. j- W- H& i
  50.   tmp |= (3<<11);
    & k* t  T! a( I; ]
  51.   __writeMemory32(tmp, 0x40022000, "Memory"); // reset caches
    9 [( X3 }8 h7 p  ^# ~: ^
  52.   
    ) M4 Z# V1 [5 @- ?5 H
  53.   if ((0xFF & __readMemory32(0x40022020,"Memory")) != 0xAA)
    3 u; p& W; z$ L# Q) ]3 x
  54.   {! q- k- W8 N4 C5 j6 I5 S5 y5 _8 f
  55.     1 V6 g4 u0 e- A
  56.     if (!__messageBoxYesCancel("Do you want to perform mass erase to unlock the device?", "Unlocking device"))4 `7 D3 }6 k" r3 q* a2 O
  57.     {0 G6 C6 G8 Q3 h! l8 ?
  58.       __abortLaunch("Unlock cancelled. Debug session cannot continue.");
    - M% P0 @2 `0 V% [4 p; l8 u1 B
  59.     }* |# \* F& S3 N. s4 Q3 O0 \8 I
  60. $ e" r' I. L; z: F9 F/ S+ l
  61.     __writeMemory32(0x45670123, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY1;
    , t$ y* R+ ?8 [. @+ J4 H# Z
  62.     __writeMemory32(0xCDEF89AB, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY2;
    % T' ^* t6 ]0 N4 {, Y
  63. //    __writeMemory32(0x00000000, 0x40022000, "Memory"); // Flash 0 wait state$ j5 M+ e" c' g3 H# {! H0 N
  64.     __writeMemory32(0x08192A3B, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY1;2 W$ U+ W8 y0 D0 `  I- ^) ?
  65.     __writeMemory32(0x4C5D6E7F, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY2; . \$ ~! J3 o3 r1 P" w. ~3 |( L% u6 k
  66.       
    ; A- N5 @7 D' b% J* J
  67.     __message "Setting FLASH readout protection level 0 (disabled)";
    " _' K3 S, m+ q6 ~+ i
  68.   9 k1 K: O5 u2 q) V, ^* F9 \
  69.     __writeMemory32((__readMemory32(0x40022020,"Memory") & 0xFFFFFF00) | 0xAA, 0x40022020, "Memory");     // Disable readout protection. a/ U" ]6 e. n; o9 A2 J
  70.    
    : h1 ?9 n4 I/ v; \
  71.     * N) I7 ?& p6 `3 G
  72.     __writeMemory32((1<<17) | __readMemory32(0x40022014,"Memory"), 0x40022014, "Memory");                 // Set the Options Start bit OPTSTRT9 v* f4 Z! {: Y
  73. ; C" {. A* ~7 h7 f0 u. x
  74.     while((1<<16) & __readMemory32(0x40022010,"Memory"));  // Wait while FLASH busy
    * |$ J* Z% e7 d
  75.         
    0 a: l/ K* h. i) I0 y
  76.     __writeMemory32((1<<27) | __readMemory32(0x40022014,"Memory"), 0x40022014, "Memory");                 // Set the OBL_LAUNCH to Force the option byte loading/ D# W1 ~  b* A! z% ]7 A' X
  77.       
    # W5 b7 l9 \/ X! B8 u
  78.   }
    ( p- I4 c+ L: r3 h2 J
  79. }
    4 a' G5 r, }% J- o; }; k: r1 ~

  80. : Q9 u) h  H8 v  O5 i
  81. execUserFlashExit()/ Q9 h% I) Y7 N" i0 b
  82. {
    ( L' H- B4 b% G; J2 C" l
  83. __message "Entry execUserFlashExit";2 M/ u% E* E/ d, [' ?5 o
  84.   if(!((1<<16) & __readMemory32(0x40022020,"Memory")))
    " ?6 S0 O" g5 e  a
  85.   {
      f4 w6 l6 e3 s% C! F# {) U
  86.     __writeMemory32(0x5555,0x40003000,"Memory");
    / B0 K! C; j! C9 E: f4 b. |
  87.     __writeMemory32(IWDG_PR,0x40003004,"Memory");
    0 ^1 M* i* k- e* m" ^
  88.     __writeMemory32(IWDG_RLR,0x40003008,"Memory");
    6 h* _$ U; O( M& E& S7 O: G4 B
  89.     __writeMemory32(0xAAAA,0x40003000,"Memory");2 t% R$ p$ F. J& r
  90.   }
    - Y# `7 s0 J, g. b2 N% W5 f. |. M
  91. 0 d* t- z' r- ]( M6 D9 \
  92.   //Restore registers modified earlier
    * {/ ?: T+ Y! l8 x% O2 Q' a$ r" _6 Y
  93.   __writeMemory32(RCC_CFGR, 0x40021008, "Memory");
    + c: F+ r1 D+ z5 d; D
  94.   __writeMemory32(RCC_CR, 0x40021000, "Memory");
    / ^' y% J; l& w; A7 ]. y2 J
  95.   __writeMemory32(RCC_CIR, 0x40021018, "Memory");
    & G6 ?8 l$ T9 }  D. t7 b$ F% Q

  96. ( L, x% ^: Z. s: f
  97.   __writeMemory32(FLASH_ACR, 0x40022000, "Memory"); 0 q( N$ y: o1 w$ V3 v% W; t
  98. }
复制代码

/ _6 t$ _1 W+ m# l
从上述.mac 文件中定义了如下宏函数,并在入口中添加了打印输出:

( k- h9 }& ]: e; @5 B1 }5 l6 S6 c
execUserFlashInit()

& H+ y# E& |1 X, V  `# \4 e
execUserFlashExit()
" X# ]" H$ L$ S

. V1 l2 J) h1 a3 p  U
5.下载验证

; U7 }0 |. y4 T( w( P1 z, V5 d
macros 文件是可以被C-SPY 调用的执行文件,为了验证个人的猜想在execUserFlashInit 入口和出口追加了log 输出,来确认猜测是否正确。
" Q  g  s) C; R6 K) C( q( j/ E. b2 W" j& m有了上述的配置信息及flash 的初始化处理,flash loader程序就可以吧编译的二进制下载到板子上执行了。准备下环境验证下上述猜测是否正确。

. M7 d, x* o) \* X  K4 g2 e7 C! c
debug_loader.png
, |4 N* M' d' ~5 m& S

; A  Y2 J" y4 ?- S1 U) R0 `
从debug log 窗口可以发现mac 文件内定义的函数入口打印输出跟预期的是一致的,同时从log 个中也可以看出flash loader(FlashSTM32L4xxxRAM48K_DUALBANK.out) 程序是按照上述描述的方式被C-SPY 加载到目标系统。

  y% y0 W3 r: C
  1. Flash loader example9 r6 U0 `" c7 @. m6 e
  2. The following example shows the source code for a complete flash loader (except the source* Y* C4 w4 f, S: D
  3. code for the framework), but with a flash programming algorithm which simply copies bytes% R" y7 d# O) ?0 p
  4. from the RAM buffer to the destination address:1 T: z2 m3 X. v& H7 k! @* u5 P
  5. #include "flash_loader.h"
    * s+ T7 b# s6 m( ~3 s
  6. uint32_t FlashInit(void *base_of_flash, uint32_t image_size,
    7 B0 C9 S" b4 r" U
  7. uint32_t link_address, uint32_t flags)" m8 q1 y& S) h  W, }
  8. {4 m, G* a, m1 t! \% H6 J6 g9 b
  9. return RESULT_OK;( {. G  A5 r6 A% ^
  10. }6 F9 F. d  R* ^
  11. uint32_t FlashWrite(void *block_start,& {5 A5 A: u" S4 J# x) k  P3 \: A
  12. uint32_t offset_into_block,7 R  D4 ?& X# T4 }
  13. uint32_t count,
    # S' r: k" S2 K+ U/ L! r% z5 c
  14. char const *buffer)
    ) c5 M3 `7 K- U4 m" X& g4 [/ w
  15. {1 v2 V" L4 H; K6 m7 \3 _, ^& q3 K2 j
  16. char *to = (char*)block_start + offset_into_block;
    ( O5 S" D# J+ ?: j  X* \6 c
  17. while (count--)' B9 c) d$ i: Y, K5 Z6 ]
  18. {
    * w: x# C# D- Y  G" B! y
  19. *to++ = *buffer++;
    4 P8 Z1 q6 }  x
  20. }) p$ Q7 ]! ?" o' G3 @* @% ?/ M* {
  21. return RESULT_OK;
      O/ M5 H# J3 R5 B
  22. }! t3 {' C; m: y. p: M
  23. uint32_t FlashErase(void *block_start, uint32_t block_size)
    ) ^0 _) x. `* _: J. X
  24. {: e% z& N5 u0 n# }% q* B% P" m
  25. char *p = (char*)block_start;8 y/ s4 n$ L8 z# z
  26. while (block_size--)2 [& N" s! R; X) `- g
  27. {5 K/ ]# {( B. G1 J1 g, u. ~
  28. *p++ = 0;3 F. Q& F7 ]+ ~0 Z8 b/ L, ?# @
  29. }+ f: [8 r; ^5 b; m. ~. X
  30. return RESULT_OK;% ^, U* ^7 G( D$ ~% p
  31. }+ {0 m8 `4 I3 f7 u/ j# t
  32. The parameters to FlashWrite and FlashErase, in combination with the flash memory base7 p& _: U% ], k& B* Z2 N/ U
  33. address given in FlashInit, fully specify the addresses of the portions of the flash memory to. X0 A, N  H1 x# k# X. n
  34. be programmed. Thus, a given flash loader can be used for any number of different flash
    , J/ T* f& R) b% J$ g! }  F" j) m
  35. devices, with different total size, page size, or block layout, provided that they all employ the
    ( Q% }9 n7 f$ |5 e3 h$ P
  36. same flash programming algorithm. The flash memory configuration file (.flash) is used for
    4 T2 b& M; D$ \
  37. specifying such variations between flash memories.
    8 K3 v; h: C4 I% i4 D0 M
  38. The reference section at the end of this document describes all framework functions in detail.
复制代码
9 ?4 b% I4 U; M
从上述flash loader 的示例程序中实现了FlashInit/FlashWrite/FlashErase 三个api 函数,我们可以objdump 下flash loader 程序看下内部是否是按照上述方式实现了对应的接口。
+ h9 ?. u3 f3 p4 K" ]& k1 e' \
  1.                 FlashInit:* {9 l' B! G3 U$ o
  2.   0x200000c4: 0xb510         PUSH   {R4, LR}
    . t$ c5 M% ^. @/ ]
  3.   0x200000c6: 0x494a         LDR.N  R1, `.text_8`          ; flash_ie8 x$ z  m; n: H) I6 f% D: w
  4.   0x200000c8: 0xf500 0x2200  ADD.W  R2, R0, #524288        ; 0x80000
    2 |: ?9 @9 R% S  O/ x+ A
  5.   0x200000cc: 0x604a         STR    R2, [R1, #0x4]* Y  s: y! G- w; I% b9 ~: N
  6.   0x200000ce: 0x2300         MOVS   R3, #0
    ( [# s6 q- V- N& Q0 m+ a7 |
  7.   0x200000d0: 0x2200         MOVS   R2, #0. B: J# o6 \* N# R% Q! u: [: w& S  C
  8.   0x200000d2: 0x700a         STRB   R2, [R1]) ]: ~9 B& t7 j- z# |
  9.   0x200000d4: 0x9a02         LDR    R2, [SP, #0x8]
    9 C) G% K; @) E, M! l
  10.   0x200000d6: 0xe000         B.N    @200000da
    6 ^4 f5 R- b9 ?9 t8 `; l0 J+ ~
  11.                 @200000d8:5 O) @( S4 E9 a$ J9 O
  12.   0x200000d8: 0x1c5b         ADDS   R3, R3, #1
    ( Y8 V- H( v) O/ }9 ]
  13.                 @200000da:+ ^& c$ X* u9 P2 _6 y
  14.   0x200000da: 0x4293         CMP    R3, R2
    ) H* n0 p, C& g2 K! u1 H2 b5 s6 C
  15.   0x200000dc: 0xdbfc         BLT.N  @200000d8! x$ l3 U* q* _* n
  16.   0x200000de: 0x4a45         LDR.N  R2, `.text_9`          ; 0x40022008 (1073881096)
    / d6 b& q% d# g' ]- Z
  17.   0x200000e0: 0x6993         LDR    R3, [R2, #0x18]
    8 }3 a! ~% u5 {) }0 B
  18.   0x200000e2: 0x029b         LSLS   R3, R3, #10$ a; s- p- a. h( H
  19.   0x200000e4: 0xd507         BPL.N  @200000f6- M+ B- I9 w5 X3 f, f
  20.   0x200000e6: 0x4b44         LDR.N  R3, `.text_10`         ; 0x1fff75e0 (536835552)
    2 D6 g: Y' _8 |
  21.   0x200000e8: 0x4c44         LDR.N  R4, `.text_11`         ; 0x3ffc00 (4193280), p/ b2 U3 ?, }/ l
  22.   0x200000ea: 0x881b         LDRH   R3, [R3]
    0 s& w5 m5 h0 Y# r4 D3 K1 q4 R
  23.   0x200000ec: 0xea04 0x2383  AND.W  R3, R4, R3, LSL #10( W- b( k/ u# t% N" E8 p
  24.   0x200000f0: 0xeb00 0x0063  ADD.W  R0, R0, R3, ASR #1
    * L. n8 I& _& V' `, E$ t
  25.   0x200000f4: 0x6048         STR    R0, [R1, #0x4]# o( k( _$ u( I# |& C8 _# r
  26.                 @200000f6:6 h9 j' N8 X+ O9 e) n, W, c' _9 W
  27.   0x200000f6: 0x4842         LDR.N  R0, `.text_12`         ; 0xe000e100 (-536813312)
    1 S+ v1 ]/ q5 K+ C. e
  28.   0x200000f8: 0x4b42         LDR.N  R3, `.text_13`         ; 0xe000e180 (-536813184); L; @/ A. `- b) |
  29.   0x200000fa: 0x6800         LDR    R0, [R0]: c. c* k8 a* v. P, b
  30.   0x200000fc: 0x06c0         LSLS   R0, R0, #27
    % p6 c& p2 p$ f3 l. u; h; ?; W
  31.   0x200000fe: 0xbf44         ITT    MI  Z7 }% r3 Q0 A
  32.   0x20000100: 0x2001         MOVMI  R0, #1
      ^- a: ]! I; C
  33.   0x20000102: 0x7008         STRBMI R0, [R1]3 [3 v6 @4 h! h' ~1 ]" x- R8 m
  34.   0x20000104: 0x2010         MOVS   R0, #16                ; 0x106 u) P+ i* T- R; m& _
  35.   0x20000106: 0x6018         STR    R0, [R3]
    4 v4 _3 M! |: Z4 A% C! D0 P
  36.   0x20000108: 0x4b3f         LDR.N  R3, `.text_14`         ; 0xc7000ff8 (-956297224)
    . R; ?' G( Y& x
  37.   0x2000010a: 0x68d0         LDR    R0, [R2, #0xc]
    . G, i: x" V3 d0 M8 q
  38.   0x2000010c: 0x4018         ANDS   R0, R0, R3" c  T+ ]9 y- F6 s8 @# V6 {0 w5 _) D7 X4 B
  39.   0x2000010e: 0x6088         STR    R0, [R1, #0x8]
    2 n, b( K" y2 E, J* e4 E7 M
  40.   0x20000110: 0x483e         LDR.N  R0, `.text_15`         ; 0x45670123 (1164378403)* I& T- D& e% G, d8 A
  41.   0x20000112: 0x6010         STR    R0, [R2]  H4 j$ i& s# o# h  Q( U
  42.   0x20000114: 0x483e         LDR.N  R0, `.text_16`         ; 0xcdef89ab (-839939669)
    8 m3 i& w& o. \) w7 {7 c
  43.   0x20000116: 0x6010         STR    R0, [R2]+ [; K& a8 x, k: a
  44.   0x20000118: 0x68d0         LDR    R0, [R2, #0xc]
    * C$ ]; @# C9 C( |; u- T
  45.   0x2000011a: 0xf020 0x60c0  BIC.W  R0, R0, #100663296     ; 0x6000000
    ( b% w6 }3 Q+ x& F. q6 Q
  46.   0x2000011e: 0x60d0         STR    R0, [R2, #0xc]% q+ H; G9 P+ O* E
  47.   0x20000120: 0x68d0         LDR    R0, [R2, #0xc]
    0 h; Y5 h7 w3 n6 X" S
  48.   0x20000122: 0xf040 0x7080  ORR.W  R0, R0, #16777216      ; 0x1000000
    * |5 E2 j% X1 S1 n0 i1 B
  49.   0x20000126: 0x60d0         STR    R0, [R2, #0xc]
    ; F1 `! }  o# U, Z2 m0 E" `" V; i. g2 e
  50.                 @20000128:
    ! V( P1 E6 Z  J0 G+ U" S" }2 g
  51.   0x20000128: 0x6890         LDR    R0, [R2, #0x8]
    & q  X1 P* }/ i! |; z# H
  52.   0x2000012a: 0x03c0         LSLS   R0, R0, #15
    % m( q: K" k9 I) \
  53.   0x2000012c: 0xd4fc         BMI.N  @20000128
    3 k* e5 Y" t0 }! D( P
  54.   0x2000012e: 0x2000         MOVS   R0, #0
    5 A% a+ b( i! Q0 i" D) N
  55.   0x20000130: 0xbd10         POP    {R4, PC}& @% P: Z! z5 C
  56.                 `.text_5`:
    . S( A9 F  k' [9 N" B8 t
  57.                 FlashWrite:; o3 |0 q6 `7 x; A1 o; [, ]( v0 B
  58.   0x20000132: 0xb5f0         PUSH   {R4-R7, LR}
    9 Q5 o% F, z  p( r- ]9 v
  59.   0x20000134: 0xf240 0x15ff  MOVW   R5, #511               ; 0x1ff/ d8 R" f4 e* w. W
  60.   0x20000138: 0x1844         ADDS   R4, R0, R1
    ' ~2 x* R" B% {$ U) ?7 ~$ f* I3 _
  61.   0x2000013a: 0x4936         LDR.N  R1, `.text_17`         ; 0x40022010 (1073881104)1 x8 f7 m; i5 Q0 z5 a
  62.   0x2000013c: 0x600d         STR    R5, [R1]
    + N7 H6 k! K8 B# D; T* Z- t8 @
  63.   0x2000013e: 0x2000         MOVS   R0, #0- Z" U$ x3 v$ h
  64.   0x20000140: 0x684d         LDR    R5, [R1, #0x4]9 P& t. E/ D* Q2 j. b1 F
  65.   0x20000142: 0xf045 0x0501  ORR.W  R5, R5, #1$ v; l* w; w$ w1 k+ ~
  66.   0x20000146: 0x604d         STR    R5, [R1, #0x4]8 P" C3 p% X( t- m- d7 V5 \1 l9 k
  67.   0x20000148: 0xe000         B.N    @2000014c. a4 e% r3 @, B$ x
  68.                 @2000014a:
    4 {. I& c6 e, D0 t
  69.   0x2000014a: 0x3a08         SUBS   R2, R2, #8
    * y  m: M0 z9 o( W3 \
  70.                 @2000014c:$ O' M8 a# |- g/ q/ [" u6 c- _
  71.   0x2000014c: 0xb162         CBZ    R2, @20000168
    . O+ w! H$ F5 k' j' U' z: [
  72.   0x2000014e: 0xe8f3 0x6702  LDRD   R6, R7, [R3], #0x8+ E! r) @: m5 Z6 g3 g2 ^
  73.   0x20000152: 0xe8e4 0x6702  STRD   R6, R7, [R4], #0x8
    $ B* N. ?( W5 x  u- N+ y  P
  74.   0x20000156: 0xbf00         NOP
    + T/ a/ t; \* @4 K3 H: y/ T. |- L
  75.   0x20000158: 0xbf00         NOP. d0 @" @. s; n. [- ~2 k3 k
  76.                 @2000015a:
    4 c4 A' t. s' T( ]9 W8 H+ k
  77.   0x2000015a: 0x680d         LDR    R5, [R1]
    - c$ M3 U4 m) I8 x
  78.   0x2000015c: 0x03ed         LSLS   R5, R5, #15& J  ]' K/ B1 n0 \+ f( E' r
  79.   0x2000015e: 0xd4fc         BMI.N  @2000015a2 M  m$ d* R; b, h0 ?2 U7 U
  80.   0x20000160: 0x680d         LDR    R5, [R1]
    + ?" B( E  s* c: q" w2 r
  81.   0x20000162: 0x07ed         LSLS   R5, R5, #31& F. ?2 o1 W0 M. u8 E& Q$ _, x' u
  82.   0x20000164: 0xd4f1         BMI.N  @2000014a
    # A8 M4 j6 P: T% U+ E
  83.   0x20000166: 0x2001         MOVS   R0, #1
    4 u0 m  \* l0 K% f3 j& c/ J) y( V5 Q
  84.                 @20000168:
    5 |  K8 N% j! Y6 |- _$ a
  85.   0x20000168: 0x684a         LDR    R2, [R1, #0x4]3 d( h+ H! n/ c6 c9 c
  86.   0x2000016a: 0x0852         LSRS   R2, R2, #1% ]; u$ W6 p. a0 G
  87.   0x2000016c: 0x0052         LSLS   R2, R2, #1' _7 n6 _* Y+ q3 y4 E
  88.   0x2000016e: 0x604a         STR    R2, [R1, #0x4]/ A9 x: @& K# s( P. R$ u7 F9 V' h
  89.   0x20000170: 0xbdf0         POP    {R4-R7, PC}
    ( z& l, F. j' a3 Q  s1 e; N+ M
  90.                 `.text_6`:7 N' l3 C! P( u" s4 {8 v, ^# G
  91.                 FlashErase:
    ; ^+ _$ c/ {% C" h  y6 c5 m5 S2 u
  92.   0x20000172: 0x4a28         LDR.N  R2, `.text_17`         ; 0x40022010 (1073881104)
    ( c  Y* \8 ?* x+ a  l$ [  v) i. e  Y
  93.   0x20000174: 0xf240 0x13ff  MOVW   R3, #511               ; 0x1ff/ e5 I" ~' \3 ]" f- O$ }/ \
  94.   0x20000178: 0x6013         STR    R3, [R2], {# m! |! F( L% b; e
  95.   0x2000017a: 0x4601         MOV    R1, R0
    ) K* S. {7 t' n/ a8 o. o( a- R
  96.   0x2000017c: 0x6853         LDR    R3, [R2, #0x4]$ b6 E5 }; t/ [6 V
  97.   0x2000017e: 0xf36f 0x03cb  BFC    R3, #3, #9
    * M9 X7 d. F5 O* i1 g
  98.   0x20000182: 0x6053         STR    R3, [R2, #0x4]
    7 d; z6 B: Y8 m3 O
  99.   0x20000184: 0x2000         MOVS   R0, #0# s1 c# T  A' X4 q6 `# N
  100.   0x20000186: 0x4b1a         LDR.N  R3, `.text_8`          ; flash_ie
    ! J8 D: N) H# S( T7 w: N8 {% I  Z, D# a
  101.   0x20000188: 0x685b         LDR    R3, [R3, #0x4]
      Q( X& `. U, i2 U( y( D) H
  102.   0x2000018a: 0x4299         CMP    R1, R3
    9 z/ e/ u* _( N1 P+ M" ~
  103.   0x2000018c: 0xd203         BCS.N  @20000196
      ?2 j9 W* J9 v9 |; q' n
  104.   0x2000018e: 0x0a09         LSRS   R1, R1, #8
    , @; i$ G5 x; i& q1 C5 e- W" [
  105.   0x20000190: 0xf401 0x61ff  AND.W  R1, R1, #2040          ; 0x7f86 X  B6 N  S& Q5 R
  106.   0x20000194: 0xe007         B.N    @200001a6; y2 ~9 v; ?$ \1 Q* d% J
  107.                 @20000196:
    $ O" [* m6 {* ~3 s& G
  108.   0x20000196: 0x1ac9         SUBS   R1, R1, R3' ]3 q. v- u4 V
  109.   0x20000198: 0x6853         LDR    R3, [R2, #0x4]9 T. l8 H- d) N2 m; _
  110.   0x2000019a: 0x0a09         LSRS   R1, R1, #8/ S, k+ ^. j* N
  111.   0x2000019c: 0xf443 0x6300  ORR.W  R3, R3, #2048          ; 0x800
    . i& }) E8 U' \4 F
  112.   0x200001a0: 0xf401 0x61ff  AND.W  R1, R1, #2040          ; 0x7f8
    " z/ U$ h% H+ O5 ^
  113.   0x200001a4: 0x6053         STR    R3, [R2, #0x4]
    7 i9 W  F/ I, t
  114.                 @200001a6:
    " w/ G4 b" B: ~' I: @* g( m
  115.   0x200001a6: 0xf041 0x0102  ORR.W  R1, R1, #2- \# Z0 `0 z1 Z1 N, [
  116.   0x200001aa: 0x6853         LDR    R3, [R2, #0x4]
    * |2 g% z4 y7 d% C1 u. j. i
  117.   0x200001ac: 0x4319         ORRS   R1, R1, R3; q, D# q' o" q* W
  118.   0x200001ae: 0x6051         STR    R1, [R2, #0x4]
    ( j6 ~" s( l, x9 a$ g9 s# h
  119.   0x200001b0: 0x6851         LDR    R1, [R2, #0x4]
    3 ?2 L" S! r5 d- B% m' x9 W5 {
  120.   0x200001b2: 0xf441 0x3180  ORR.W  R1, R1, #65536         ; 0x100003 g7 P! w( a  H) Z2 l0 q
  121.   0x200001b6: 0x6051         STR    R1, [R2, #0x4]" M; w: U! f; C8 T5 ~: M8 a
  122.   0x200001b8: 0xbf00         NOP
    1 K+ N. R: P1 ~) f
  123.   0x200001ba: 0xbf00         NOP8 S$ v% ?3 X& [" G" P' y; M0 r
  124.                 @200001bc:; q* C6 V( G( X. @7 o6 n( o5 Q
  125.   0x200001bc: 0x6811         LDR    R1, [R2]
    * S/ P% z; S9 L1 f0 J
  126.   0x200001be: 0x03c9         LSLS   R1, R1, #15
    # Y$ D7 Q$ M0 L# ?- O% Q- P
  127.   0x200001c0: 0xd4fc         BMI.N  @200001bc# z7 A3 d% v& R  X* R
  128.   0x200001c2: 0x6811         LDR    R1, [R2]
    ! O4 W: U& B: G% W) A. N+ t
  129.   0x200001c4: 0x07c9         LSLS   R1, R1, #31
    % M7 w) N( @4 l; g
  130.   0x200001c6: 0x6851         LDR    R1, [R2, #0x4]% u" v: n1 ~  U
  131.   0x200001c8: 0xf021 0x0102  BIC.W  R1, R1, #28 B  E7 N& g2 Z7 {
  132.   0x200001cc: 0xbf58         IT     PL6 R5 w' }2 }- [8 X4 z% w+ x, T
  133.   0x200001ce: 0x2001         MOVPL  R0, #1# H' T8 f5 l1 s9 ~/ O
  134.   0x200001d0: 0x6051         STR    R1, [R2, #0x4]0 n* a4 N, A6 A0 `+ x, [: L
  135.   0x200001d2: 0x4770         BX     LR
复制代码

# K: K- y# @1 {2 m8 }4 M1 S* x9 c
上述通过  
ielfdumparm.exe  FlashSTM32L4xxxRAM48K_DUALBANK.out  -o FlashSTM32L4xxxRAM48K_DUALBANK.ASM --code
命令dump 出来的flash loader 程序,跟预期的保持一致实现了FlashInit/FlashWrite/FlashErase 这组API函数,而且通过反汇编的函数地址信息也可以看出对应的函数的link 地址并不是falsh 区域而是内部RAM 的地址,跟C-SPY 调用flash loader 程序的流程是一致的。

3 R6 H( F9 o" w7 z# x# N6 l

/ D2 h' K2 G% x6 c4 l4 l3 O+ e
资料分割线
FlashLoaderGuide.ENU.pdf (233.17 KB, 下载次数: 8)
收藏 评论0 发布时间:2022-12-31 12:51

举报

0个回答

所属标签

相似技术帖

官网相关资源

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