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

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

[复制链接]
andey 发布时间:2022-12-31 12:51
1.IAR 下载配置
" O9 I; p6 J- ]6 ^5 m, R本次使用的硬件环境为MUCLEO-L476开发板,官方下载的软件包中打开IAR的工程文件,IAR的下载配置如下:
IAR_DOWNLOAD.png
; c9 ^3 m$ v" {$ {
默认配置是使用IAR 系统默认配置文件,我们勾选上Oveerride default .board file文件。
IAR_OVERRIDE.png
* V0 `- o8 S( L* Q. K$ h# H" N
从下载配置中看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 的更新任务。
0 B3 l  ]. Z& M1 m. {2 W/ i
The flash loader
' }. Y' f: V4 p2 ~9 E0 |A flash loader is usually a rather small program which can program one or more flash memories.
, F9 l& m- u- p/ lThe flash loader consists of a small set of functions, mainly for erasing or writing designated8 N' e2 q2 g" |  c
portions of the flash memory. C-SPY downloads this program into RAM (it must be linked to an
4 J" `4 \, R0 zaddress in RAM). To run the program, C-SPY sets the PC to one of the functions in the flash8 i) N& |, J% U# F
loader, writes data and directives for that function into a RAM buffer, and starts execution.
7 Q8 f: I) l& a9 bWhen the function returns, execution will hit a breakpoint. C-SPY will then know that the
+ i6 p6 O2 n6 ]4 r- }  x6 B4 afunction has finished and can proceed to make further

6 d/ d" f1 r7 W. R$ t; Z" @' ^
从如下图片能更清晰的看出flash loader 的工作流程:
! r# l) k5 d" N0 [6 u, ^
flah_load.png
  • 通过 C-SPY 将 flash loader 程序加载到目标系统预留的RAM区域。
  • 通过 C-SPY 将需要下载测程序加载到目标系统预留的RAM区域,如果可执行程序比较大预留的RAM空间可能不能一次完全放下可以分割成多次传输。
  • 将 IMAGE 镜像通过 flash loader 将 IMAGE 镜像下载至flash.
  • 镜像下载完成后可以释放预留的RAM空间,至此已经完成下载。
    - E& f- w  d+ @: H# K) x

. {2 {3 M* o, g" {7 \+ g/ V2. *.board 文件格式说明
此*.board 配置文件的总入口,*.board 文件是什么文件,从IAR的帮助文档摘出如下说明,.board 文件是flash loader 下载镜像的配置文件被IAR 的C-SPY debug 对象引用。

% q5 x' v$ @0 R
Ext.Type of file6 A  ~  h* R! U3 F# U
Output fromInput to
board Configuration file for flash loader Text editor C-SPY
7 S: @; {# r7 h' d: ]6 K
$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxG.board文件内容如下:
  1. <?xml version="1.0" encoding="iso-8859-1"?>/ Q1 G  W) o7 y7 _4 r) _" U+ c

  2. " p4 _" n& x  W* ]) K7 ?
  3. <flash_board>6 C3 \, ?2 g7 E( O
  4.   <pass>4 B0 Z1 Y; D8 ?' X. c; C
  5.     <loader>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxG.flash</loader>
    - g3 X! B; t, p; \. H3 @
  6.     <range>CODE 0x08000000 0x080FFFFF</range>( R+ C5 u' \. |# t6 r: p/ E& q" j
  7.   </pass>0 i; w0 w( F1 j1 p, g
  8. </flash_board>
复制代码
3 h# J  |* x: ]0 i) q% ]: }5 J
从如上xml 的配置指定了,flash 的配置说明及FLASH的范围:
4 E0 U: I) b/ N* {0 i# j5 t
3. *.flash 文件格式说明
从配置选项可以看出,此.board主要的配置信息是告诉flash loader 要根据Flash STM32L4xxxG.flash 文件的配置下载镜像,此.flash 的文件是什么文件呢,从iar 的文件说明可知,.flash 文件也是C-SPY加载的文件,主要定义了flash 的相关属性配置。

. x! p) u  M$ m8 ?6 }
Ext. Type of file Output from Input to
flash Configuration file for flash loader Text editor C-SPY
3 p* }2 O# n1 q" M7 S  i6 O
  1. <?xml version="1.0" encoding="iso-8859-1"?>5 r# l% `4 d7 H& c0 c

  2. 7 }- e! P3 b2 F; [0 r3 u
  3. <flash_device>
    4 B$ ?8 L. `0 ?4 I& a# h
  4.   <exe>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxxRAM48K_DUALBANK.out</exe>% K) }, m) E. Y) N
  5.   <page>8</page>
    ; [$ o+ _1 c; R3 h1 ^, p) a
  6.   <block>512 0x800</block>8 e' i4 I* V4 j7 Z8 x1 O- H
  7.   <flash_base>0x08000000</flash_base>
    3 {7 y5 B5 Y7 q5 T4 T& e3 ^5 V
  8.   <macro>$TOOLKIT_DIR$\config\flashloader\ST\FlashSTM32L4xxx.mac</macro>$ W" q/ A( @1 O2 p
  9.   <online>1</online>  A. k8 A# U( e2 b) D
  10.   <aggregate>1</aggregate>  - w" ^  T5 w# G. |
  11.   <args_doc>"--skip_erase" -Don't erase blocks that read empty.</args_doc>7 E$ l- ^8 M7 i
  12. </flash_device>
复制代码
如下是上述 xml 文件的配置项说明:
To accommodate a large range of different flash memories, C-SPY uses a few concepts which/ Y# T+ b' T# N1 n3 |
detail the characteristics of flash memories.' V5 q$ [1 q, B3 L4 Z  U, i( ~
Page$ [* [% N& }2 E9 m" |7 @
A page is the smallest writable unit of the flash memory. Many flash
5 e3 W2 }8 s! w& Imemories cannot write less than for example 128 or 256 bytes in a
1 r5 @. z( {8 u8 j! D% {- d) xsingle write operation. C-SPY will never request the flash loader to write, D4 _$ d+ W5 \! B+ A% F
anything smaller than a page, and uses padding if necessary to fill out a
0 s5 m7 Z9 B6 T2 ]; }page. Of course, some flash memories have no such restrictions and can
3 u( Q% e% m2 ~  q: cspecify a page size of 1 byte.  N+ O3 \) h( x$ @/ s
Block% g) [% J0 {% Z6 D2 H/ S) G
A block is the smallest erasable unit of the flash memory. For example,8 i  R% ]! f# b8 n% j- s0 ]
a flash memory with a 256-byte page size could still require that flash  N( H1 j! j9 b. U; L5 ^+ J
memory should be erased in 4-Kbyte chunks. The block size must
0 }3 o5 R. f$ B! \7 J5 `& N. }1 Lalways be a multiple of the page size. A flash memory can consist of
! C8 P" Y( P+ _; hseveral blocks of different sizes. It can also lack such restrictions, in
0 U, ^5 j  E) hwhich case the block size would be the same as the page size.+ i3 r9 ]: k8 f: N
Base address
( s* [7 t, o. \2 X3 LThis is the start address of the flash memory, when it is written. Some* g' u" @8 e7 H( }! E" i
flash memories are simply memory mapped into a fixed address range) p, b4 v* d. r$ ~) I" t
and the base address is then the start of that range. Other flash memories
  C) s8 s" O0 g' Zare mapped into different addresses when being programmed and when
9 s1 R' A8 g0 i( B! hthe application is later executing. The base address is then the address
. k# |) z$ T8 k% h/ ?where these memories are mapped when being programmed. Yet other
) q3 ]9 D/ o  m) {flash memories are not memory mapped at all, but work more like
" e1 ^: f  ?3 C9 yexternal disk-like devices. The base address is then simply the preferred
% o8 I0 |& S1 T/ n4 j* Q' caddress to be used for the start of the memory when it is being# ^# M2 s/ l1 X' e9 U; n: Q6 U, Z7 v; O
programmed.# X5 D& \% @; y# {. p: Y  V! _4 b
From the C-SPY perspective, a flash memory starts at a given address and consists of a sequence
; _) F$ m1 T& g0 Xof blocks (possibly of different sizes), each of which consists of a number of pages. The
2 |$ J( I8 e) z2 G7 r* A- P7 jsequence can also contain gaps.

9 J$ c4 d1 K% X6 Y/ j
从上述配置文件解析:
STM32L476 的 page 为8byte,共有512 个block 每个  block 大小为2k,总大小为1M,base 地址为0x0800 0000。
flash_page.png
: c; |1 X: E) Q( w, m& W3 t
FLASH main features
& x3 ?/ S; j# i" B$ w) V3 Z% c6 @• Up to 1 Mbyte of Flash memory with dual bank architecture supporting read-while-write
6 B; W! @* c5 u( T5 N; e" G. h$ Icapability (RWW).
8 S) _+ P& n7 x) P& I8 n- u4 m* h• Memory organization: 2 banks (Bank 1 and Bank 2)
& B9 Q+ F3 Y; A; V/ O8 `- U% c– main memory: 512 Kbyte per bank
: n: t; d! O) C3 z) l  [– information block: 32 Kbyte per bank
' O5 p9 Y6 ?% ]5 F; v! H• 72-bit wide data read (64 bits plus 8 ECC bits)1 j/ v* T* w6 f. A) {% B7 C) V
• 72-bit wide data write (64 bits plus 8 ECC bits)
3 u" D4 z$ _5 f" s% v3 x: u• Page erase (2 Kbyte), bank erase and mass erase (both banks)
) R5 I) B+ N9 e+ Q9 y( W1 Y% {
从上述描述可以看出flash 的最小读写单位是64bit 8bit ECC,最小的编程单位是8byte,每个最小擦除单位为2kbyte,xml 配置和芯片手册里FLASH 的layout 布局是保持一致的。

2 }& `& O  d, e4 \# g: E/ }
0 ^- |+ K( ?; E
4. *.mac 文件格式说明
.mac 文件定义了 C-SPY 调用的宏函数,如下宏函数会在 flash loader 的不同阶段调用宏函数。

$ M. D3 ^9 F/ x! V, n
1 H# i1 L% m7 J: N; M
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 in+ w* d+ f% h2 n4 v. P# J. d
conjunction with downloading the flash loader.
There are three C-SPY$ F" Q2 n1 U2 ^  b6 }3 t1 Y6 L
macro functions that will be called automatically if they are defined in
( v' L1 z4 T; z! d% Mthis macro file:( j( U% ]  r& q- r- E* Z
execUserFlashInit is called immediately before loading the flash; G3 n" B1 Q4 j. X- a  w- [
loader.' Y; S/ @( N+ W  Q- k
execUserFlashReset is called immediately after the reset that3 a- S, r( Z; B5 Y5 U: f
follows the loading of the flash loader.! p8 W( W- c, P) o: O0 o  k
execUserFlashExit is called immediately after flash loading has* ]* D' u# ]- p; A
finished, but before the flash loader is unloaded.
, o" |, k3 d6 Q0 S& b8 o5 I& _
FlashSTM32L4xxx.mac 内容如下:
  1. __var RCC_CFGR;. m! z* Z: q& S8 }4 W$ K6 |
  2. __var RCC_CR;
    4 e' f7 @/ s) |+ T
  3. __var RCC_CIR;
    1 i9 |* k, }6 O/ Q% W$ f) y
  4. __var IWDG_PR;: B$ F* L6 J* {  Y8 Z4 V+ y
  5. __var IWDG_RLR;
    . ?( T1 H- E6 l: b# J
  6. __var FLASH_ACR;
    : E1 n1 n: o6 T; h) F6 ?
  7. + ]/ {6 ~! G8 j3 g) `' X
  8. execUserFlashInit()
    & g( c# D& r, Y' e
  9. {5 i0 q3 t3 Z1 f* @. y( C
  10. __var tmp;" h$ i# x6 m. z, J/ ^, k  s5 G5 U' a2 X
  11. 5 C# O' P0 p+ t& T! Y5 \
  12. __message "Entry execUserFlashInit";
    , l0 |  `$ }# T

  13. # k  m( s2 f; a+ j+ W
  14.   //Stop watchdogs when CPU is halted& _6 ~3 \9 z/ @
  15.   __writeMemory32(__readMemory32(0xE0042008, "Memory") | 0x1800, 0xE0042008, "Memory");
    - m# d& ^) \5 w( }! l& v
  16. 6 C) L7 e- b) B3 }2 _- B  {7 y
  17.   //Check if hardware watchdog is enabled
    * P/ J  F. I9 V
  18.   if(!((1<<16) & __readMemory32(0x40022020,"Memory")))/ W0 R0 D$ Z( M3 J( }& `' k
  19.   {
    0 T$ r9 F# T' {9 K1 @
  20.     // wait PVU reset
    * A7 G( _) G$ T0 B0 A$ C
  21.     while(0x3 & __readMemory32(0x4000300C,"Memory"));5 r3 x! @- U& l! q+ w7 _4 v9 o5 V
  22.     IWDG_PR  = __readMemory32(0x40003004, "Memory");
    ' T1 q+ C# y- M8 H0 F+ D
  23.     IWDG_RLR = __readMemory32(0x40003008, "Memory");
    6 }$ ^" k1 E3 |, D
  24.   
    + ~, h- V# Z- U' M$ a2 E8 M
  25.     // unlock WDT registers
    1 Y/ u! U# W. K. l5 g
  26.     __writeMemory32(0x5555,0x40003000,"Memory");* T* m8 E5 B" o  Z
  27.     // Prescaler4 x# t% r' [2 `$ K- o
  28.     __writeMemory32(0x7,0x40003004,"Memory");
    - o9 {9 _" H, y4 r3 o3 C
  29.     // Reload) s- P7 N- ]. w# v
  30.     __writeMemory32(0xFFF,0x40003008,"Memory");; c: s7 I: j( I( t; p! y
  31.     // reload WDT
    ; A1 s7 m9 j, X  k. H
  32.     __writeMemory32(0xAAAA,0x40003000,"Memory");
    $ H4 r$ C7 Y& n/ ~4 B( u" f7 n9 v
  33.   }
    + R* p& t& o* w  B) j) q% }
  34. ' ~, X6 [9 P: `2 k
  35.   RCC_CR   = __readMemory32(0x40021000, "Memory");
    * {; w0 }: s7 a" F) e2 y
  36.   RCC_CFGR = __readMemory32(0x40021008, "Memory");8 c) a# t' H; P5 V/ k6 B2 G' z
  37.   RCC_CIR  = __readMemory32(0x40021018, "Memory");
    ( y% p1 }: w; }9 t
  38.   . y: S  c1 r: q
  39.   /*Enable HSI16 oscilator and select it as system clock*/% E) L& ^* M3 I
  40.   __writeMemory32(0x00000000, 0x40021018, "Memory");             // RCC_CIR  = 0;: l" f' [0 @3 V# {4 e& }
  41.   __writeMemory32(RCC_CR | (1<<8), 0x40021000, "Memory");   // RCC_CR_HSION  = 1;' ~/ [+ k( ~3 p) A. y
  42.   while(!((1<<10) & __readMemory32(0x40021000,"Memory")));. n! G" T/ S( ~2 q0 u9 S7 g  J
  43.   tmp = (RCC_CFGR & ~(3<<0)) | (1<<0);
    3 h4 N& ]2 D* t* s8 w  k+ V0 F8 L
  44.   __writeMemory32(tmp, 0x40021008, "Memory");                                 // RCC_CFGR_SW  = 1;
    : B" b+ s7 i, f; E0 P
  45.   
    - j, d1 s& f1 ?' R
  46.   FLASH_ACR = __readMemory32(0x40022000, "Memory");5 w2 v; ]* \  ]3 Q
  47.   tmp = (FLASH_ACR & ~(0x7<<0)) | (2<<0);) M1 E. r. n- i. ]) k
  48.   tmp &= ~(3<<9);
    & W7 S9 C/ l' Z4 B5 A
  49.   __writeMemory32(tmp, 0x40022000, "Memory"); // 2 WS (3 CPU cycles) & disable caches
    % ^% R: C) z3 ~5 c1 C& e- t
  50.   tmp |= (3<<11);
    " j" j, u) M# n
  51.   __writeMemory32(tmp, 0x40022000, "Memory"); // reset caches% C0 a5 g4 W( V* }! ?
  52.   ) k4 G5 s2 n( p3 v1 R+ J1 Q' C
  53.   if ((0xFF & __readMemory32(0x40022020,"Memory")) != 0xAA)
    % f- i- `; e& d' `% A5 T6 Z
  54.   {
    / u; w% ?0 W0 i2 l2 w% c: Y
  55.    
    $ a) q6 [+ [+ C1 d) e: Z
  56.     if (!__messageBoxYesCancel("Do you want to perform mass erase to unlock the device?", "Unlocking device"))% _! C$ S! Z& Q- l* e$ X3 J
  57.     {6 ?' a% \+ m+ t4 @5 N
  58.       __abortLaunch("Unlock cancelled. Debug session cannot continue.");
    ) |# o  f; U% d! |0 m
  59.     }0 y& J" Y9 N! H1 N2 e% k( T- m
  60. 2 o  j9 W3 o9 E
  61.     __writeMemory32(0x45670123, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY1;
    9 X/ g. l! V; m
  62.     __writeMemory32(0xCDEF89AB, 0x40022008, "Memory"); // FLASH->FKEYR = FLASH_KEY2;6 J8 o; y. S* a) C$ f- Z3 R  o8 ?. ]
  63. //    __writeMemory32(0x00000000, 0x40022000, "Memory"); // Flash 0 wait state* n1 }: |7 o- T+ h0 F  r
  64.     __writeMemory32(0x08192A3B, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY1;2 j) L3 ^. y; T+ m, J
  65.     __writeMemory32(0x4C5D6E7F, 0x4002200C, "Memory"); // FLASH->OPTKEYR = FLASH_OPTKEY2; % w* `3 F& q9 g( l# E
  66.       
    ; N- h  w' Y; \' }- J9 {1 h% E9 W
  67.     __message "Setting FLASH readout protection level 0 (disabled)";
    & D" c2 s* R* r
  68.   
    9 y4 h! u, p% a/ L" j
  69.     __writeMemory32((__readMemory32(0x40022020,"Memory") & 0xFFFFFF00) | 0xAA, 0x40022020, "Memory");     // Disable readout protection
    - Q9 _  Y! u1 N6 Q, V- W! n  y% \
  70.    
    5 L$ F4 H3 J5 {/ ?8 _3 G- D( C
  71.    
    ) ?; ~. E" v. U: |+ @
  72.     __writeMemory32((1<<17) | __readMemory32(0x40022014,"Memory"), 0x40022014, "Memory");                 // Set the Options Start bit OPTSTRT8 Q1 S  W! Y' t) _1 E9 i% Y8 |

  73. 4 B* {. ]- ]1 g2 F7 K* ?
  74.     while((1<<16) & __readMemory32(0x40022010,"Memory"));  // Wait while FLASH busy
    3 l$ C$ f( ?( z( ]' R
  75.         
    5 v! o2 f% `: R5 v- s/ U% p0 W
  76.     __writeMemory32((1<<27) | __readMemory32(0x40022014,"Memory"), 0x40022014, "Memory");                 // Set the OBL_LAUNCH to Force the option byte loading/ H' z% A4 S2 w) q9 `$ w
  77.       
    ) _: P8 \5 R' H8 h5 q* b1 ?
  78.   }0 Q5 X3 y* Q( r* k4 e* A
  79. }# A$ S, s* ~* W* y
  80. / I* R0 i* K8 g8 o2 \
  81. execUserFlashExit()! f+ j8 a" J# h4 o1 @
  82. {9 ?% {+ M' U/ f6 }* W' Z9 |4 C
  83. __message "Entry execUserFlashExit";5 `: X: K2 H6 G. }
  84.   if(!((1<<16) & __readMemory32(0x40022020,"Memory")))+ [+ M% ~' S/ z5 s8 e: h  p: {: }
  85.   {+ Z! x: l- |+ U" Q' o
  86.     __writeMemory32(0x5555,0x40003000,"Memory");
    4 k) {: m1 A" z& Q1 n0 c4 S/ `8 b
  87.     __writeMemory32(IWDG_PR,0x40003004,"Memory");! |) x0 Y& D# ^9 C
  88.     __writeMemory32(IWDG_RLR,0x40003008,"Memory");
    / e( j& r( l. ]. y  t& L" ^
  89.     __writeMemory32(0xAAAA,0x40003000,"Memory");; V% U( N5 a+ y+ }+ r
  90.   }. a! A$ ^" O! t9 u' P" M, P1 Y
  91. , D: d) r+ C8 _
  92.   //Restore registers modified earlier
    4 E; V6 u# n# F2 r5 V6 p) A
  93.   __writeMemory32(RCC_CFGR, 0x40021008, "Memory");" J9 h) c2 J6 n5 B( r# n/ X8 ]
  94.   __writeMemory32(RCC_CR, 0x40021000, "Memory");4 c+ `& a! t! b8 D$ g* r
  95.   __writeMemory32(RCC_CIR, 0x40021018, "Memory");7 b+ {. R1 R, b

  96. ' k, N  x6 ^# D0 Y- ]6 B
  97.   __writeMemory32(FLASH_ACR, 0x40022000, "Memory"); 7 w9 d* A) K1 E. Q' b  K
  98. }
复制代码
; {* ?' j3 l7 a. Z! i$ j0 Y! J
从上述.mac 文件中定义了如下宏函数,并在入口中添加了打印输出:
6 H& j" \( g& w& X
execUserFlashInit()

9 C8 {1 B( c4 P% j# D& f' b
execUserFlashExit()
% u' i5 f4 V, {2 v$ T
, P0 H& K1 O8 [4 w2 Y% A+ t+ ~
5.下载验证

; W% ~6 z% ?& `" z% p2 Z
macros 文件是可以被C-SPY 调用的执行文件,为了验证个人的猜想在execUserFlashInit 入口和出口追加了log 输出,来确认猜测是否正确。5 V' W5 ^) s7 F5 X# j
有了上述的配置信息及flash 的初始化处理,flash loader程序就可以吧编译的二进制下载到板子上执行了。准备下环境验证下上述猜测是否正确。

5 @3 T; z& s% S
debug_loader.png
1 G5 n/ |' e, k' {% d% R
* Z( M8 a  F' [8 t7 c! N5 m+ `
从debug log 窗口可以发现mac 文件内定义的函数入口打印输出跟预期的是一致的,同时从log 个中也可以看出flash loader(FlashSTM32L4xxxRAM48K_DUALBANK.out) 程序是按照上述描述的方式被C-SPY 加载到目标系统。

% |  x, A3 D" m0 h2 C7 K
  1. Flash loader example
    9 Y9 i% y. \3 X& D- d
  2. The following example shows the source code for a complete flash loader (except the source
    - y1 r( T4 X9 G2 T
  3. code for the framework), but with a flash programming algorithm which simply copies bytes. L( ^! A5 |& b  q9 w
  4. from the RAM buffer to the destination address:9 }. N& q# I, S4 D. {& ?
  5. #include "flash_loader.h"
    3 g  |$ T+ v2 E$ u& R
  6. uint32_t FlashInit(void *base_of_flash, uint32_t image_size,. R2 W' q& @& s8 y" ^% F
  7. uint32_t link_address, uint32_t flags)
    & v+ W# i( T2 M2 A# u5 I
  8. {
    1 f% N' l& q2 d$ v: N
  9. return RESULT_OK;! l5 g0 ?. }7 O& q$ H4 b) Y' {
  10. }
    & `, |& S& L  J% }* _; x
  11. uint32_t FlashWrite(void *block_start,, X$ T- v8 Y, C7 W* P, L' J: f# s9 e# k
  12. uint32_t offset_into_block,
    8 K! ?8 X; Q( N! W+ V4 K
  13. uint32_t count,- L1 b2 d* W7 R- ], z/ f
  14. char const *buffer)) w( D9 ]+ y+ {
  15. {
    $ k9 E4 V8 x. h6 M& e' c
  16. char *to = (char*)block_start + offset_into_block;  }/ v6 k# Y/ a/ g* e( }
  17. while (count--)7 Y8 e6 a# b+ P2 n$ [2 v
  18. {2 ?3 w9 _3 M0 B2 g# [
  19. *to++ = *buffer++;+ @$ G: p( W! H, L
  20. }4 Y: \; V- y. E. s& }
  21. return RESULT_OK;
    * U5 s4 W- S9 y4 v6 t
  22. }+ X; D0 j+ |3 S0 Q4 h
  23. uint32_t FlashErase(void *block_start, uint32_t block_size)1 P# e" C5 Z' V" H( I
  24. {( I' S# C) v- J# r( n# S
  25. char *p = (char*)block_start;/ A( S. H' X( E
  26. while (block_size--)( b5 j: h0 k2 X/ t' `9 u
  27. {
      R- @$ c$ B. _" q/ j% G* U
  28. *p++ = 0;! `3 f8 `  v6 {9 _  g/ r5 M" s
  29. }
    ) q* \3 L& a. F
  30. return RESULT_OK;. R0 S1 m% a* P! j, h8 I0 f
  31. }! B+ S' m) h1 Y( w2 R  p9 i% ~
  32. The parameters to FlashWrite and FlashErase, in combination with the flash memory base
    - F4 y$ H5 u4 A
  33. address given in FlashInit, fully specify the addresses of the portions of the flash memory to
    : T+ G8 W* e1 M( [
  34. be programmed. Thus, a given flash loader can be used for any number of different flash
    ' V1 f7 r9 u* X; a9 }' K2 R) p. J
  35. devices, with different total size, page size, or block layout, provided that they all employ the. A3 z- W4 }4 D+ e
  36. same flash programming algorithm. The flash memory configuration file (.flash) is used for
    4 Y- z) ]1 k9 B1 Q. k) }
  37. specifying such variations between flash memories.
    * q/ H# C8 N( j/ K6 J: A# m
  38. The reference section at the end of this document describes all framework functions in detail.
复制代码
/ p* Y5 ^. E) w" b; N& I
从上述flash loader 的示例程序中实现了FlashInit/FlashWrite/FlashErase 三个api 函数,我们可以objdump 下flash loader 程序看下内部是否是按照上述方式实现了对应的接口。
- p- a% \4 `, C( \/ b$ A6 P7 U' c" o' ?
  1.                 FlashInit:+ Z3 G( z' `* b/ y5 f; C4 a6 B
  2.   0x200000c4: 0xb510         PUSH   {R4, LR}
    6 y9 q/ N' f& r) q0 m; y
  3.   0x200000c6: 0x494a         LDR.N  R1, `.text_8`          ; flash_ie4 a4 h# J! c+ }8 D0 Z7 z
  4.   0x200000c8: 0xf500 0x2200  ADD.W  R2, R0, #524288        ; 0x80000! I" t' v' t% V
  5.   0x200000cc: 0x604a         STR    R2, [R1, #0x4]* m' F3 o8 y& W# N: ^" `6 Z! x
  6.   0x200000ce: 0x2300         MOVS   R3, #0
    ! `2 W. E" S2 L  [8 Q3 U+ }. @
  7.   0x200000d0: 0x2200         MOVS   R2, #0
    6 ?; \; f& c9 V" z/ I9 o! Z% }2 p
  8.   0x200000d2: 0x700a         STRB   R2, [R1]. K" A) x* F+ f6 |
  9.   0x200000d4: 0x9a02         LDR    R2, [SP, #0x8]0 u4 T$ a/ b- j
  10.   0x200000d6: 0xe000         B.N    @200000da4 Y* a* j: |" V) m
  11.                 @200000d8:
    $ T& K' g0 P1 ?* V0 w
  12.   0x200000d8: 0x1c5b         ADDS   R3, R3, #10 b8 ^, ^2 ~1 S! F3 f, Z: ^
  13.                 @200000da:; u$ S( Q8 H5 ?: X
  14.   0x200000da: 0x4293         CMP    R3, R2
    * f: g4 k( U0 ~2 N. c0 C
  15.   0x200000dc: 0xdbfc         BLT.N  @200000d8; ^1 e, ~  G+ l) j  K+ k
  16.   0x200000de: 0x4a45         LDR.N  R2, `.text_9`          ; 0x40022008 (1073881096)9 q& z+ N! q6 s, l8 f
  17.   0x200000e0: 0x6993         LDR    R3, [R2, #0x18], B) ?/ O! H; t$ a( X# `
  18.   0x200000e2: 0x029b         LSLS   R3, R3, #10
    + {' d8 c- [0 R3 i
  19.   0x200000e4: 0xd507         BPL.N  @200000f6; i/ a& ^0 {) r- e
  20.   0x200000e6: 0x4b44         LDR.N  R3, `.text_10`         ; 0x1fff75e0 (536835552)
      i' K! _  Z; c: X) j1 J4 o
  21.   0x200000e8: 0x4c44         LDR.N  R4, `.text_11`         ; 0x3ffc00 (4193280)
    ' i. F2 J$ d/ F- z. L# d& L
  22.   0x200000ea: 0x881b         LDRH   R3, [R3]
    - D( c. H: _5 J+ k; D
  23.   0x200000ec: 0xea04 0x2383  AND.W  R3, R4, R3, LSL #10/ V9 W. a6 P4 S8 g. s' D
  24.   0x200000f0: 0xeb00 0x0063  ADD.W  R0, R0, R3, ASR #1
    8 }* z7 E; b1 C& L$ H( W- `
  25.   0x200000f4: 0x6048         STR    R0, [R1, #0x4]
    5 Z7 ?  F2 ~. O5 A* U
  26.                 @200000f6:
    1 w* n9 j. p# x  {4 ^7 `+ x
  27.   0x200000f6: 0x4842         LDR.N  R0, `.text_12`         ; 0xe000e100 (-536813312)
    5 `3 {! O) v- a8 b
  28.   0x200000f8: 0x4b42         LDR.N  R3, `.text_13`         ; 0xe000e180 (-536813184)" x7 I! r9 |7 L- ?# e- X" O
  29.   0x200000fa: 0x6800         LDR    R0, [R0]0 ]! |* a* [. W0 g
  30.   0x200000fc: 0x06c0         LSLS   R0, R0, #27
    ' B4 h  s5 W1 P7 M+ ]0 }
  31.   0x200000fe: 0xbf44         ITT    MI
    ! z5 {4 m, @/ @# j# A4 z% N/ _5 \
  32.   0x20000100: 0x2001         MOVMI  R0, #18 ^' f9 A6 Z+ z" y6 C: B3 \
  33.   0x20000102: 0x7008         STRBMI R0, [R1]
    0 t# Z% \3 n) ~% q# [
  34.   0x20000104: 0x2010         MOVS   R0, #16                ; 0x10
    & ?1 V  q# X, B7 W0 R: p8 P8 \2 M
  35.   0x20000106: 0x6018         STR    R0, [R3]
    " ]6 _# w9 x5 G/ e; d4 D+ S
  36.   0x20000108: 0x4b3f         LDR.N  R3, `.text_14`         ; 0xc7000ff8 (-956297224)
    : j; z% w' k' R' A$ H" @; _+ G( I
  37.   0x2000010a: 0x68d0         LDR    R0, [R2, #0xc]
    9 C, B/ ]/ j9 h# t& P$ @4 E& C# W
  38.   0x2000010c: 0x4018         ANDS   R0, R0, R3
    ' m4 e" d; b" b+ T" [1 j
  39.   0x2000010e: 0x6088         STR    R0, [R1, #0x8]
    0 ?4 [: |7 D3 V& j
  40.   0x20000110: 0x483e         LDR.N  R0, `.text_15`         ; 0x45670123 (1164378403)
    3 p( \, B) t# A8 u1 I
  41.   0x20000112: 0x6010         STR    R0, [R2]
    ; P" O4 I2 i2 F0 [
  42.   0x20000114: 0x483e         LDR.N  R0, `.text_16`         ; 0xcdef89ab (-839939669)* T4 l$ H. Y5 K3 W) \- {
  43.   0x20000116: 0x6010         STR    R0, [R2]1 X5 j; j0 k" r. A  I8 q
  44.   0x20000118: 0x68d0         LDR    R0, [R2, #0xc]
    ; M  v9 M# T9 G. ~/ {3 ]' ?
  45.   0x2000011a: 0xf020 0x60c0  BIC.W  R0, R0, #100663296     ; 0x6000000- Q6 E0 Q6 r4 y- b$ V) k! Z
  46.   0x2000011e: 0x60d0         STR    R0, [R2, #0xc]
    , z# |) X) [; o- P: J$ G
  47.   0x20000120: 0x68d0         LDR    R0, [R2, #0xc]
    - M5 t/ v, p  |; r9 L, O- j; \( q' d
  48.   0x20000122: 0xf040 0x7080  ORR.W  R0, R0, #16777216      ; 0x1000000* i4 P: u5 I8 V4 p* u+ v* d8 A
  49.   0x20000126: 0x60d0         STR    R0, [R2, #0xc]. b, A0 d; N7 F
  50.                 @20000128:* N! u: {- `) v) |# r, T
  51.   0x20000128: 0x6890         LDR    R0, [R2, #0x8]3 B! U( \6 {$ _5 [! L0 y" m
  52.   0x2000012a: 0x03c0         LSLS   R0, R0, #15: g9 W& K. |! X& ^
  53.   0x2000012c: 0xd4fc         BMI.N  @20000128
      E8 O  ?- m5 L& C5 J
  54.   0x2000012e: 0x2000         MOVS   R0, #0
    2 N' I- g5 X% ?& N" X* U
  55.   0x20000130: 0xbd10         POP    {R4, PC}' y, e/ w2 i9 v/ V! U
  56.                 `.text_5`:
    0 F/ {; A  T/ x; m' S) S' d$ E
  57.                 FlashWrite:3 }& c: k) `% F# {9 A
  58.   0x20000132: 0xb5f0         PUSH   {R4-R7, LR}
    0 U8 [! N4 X* m, Q4 e
  59.   0x20000134: 0xf240 0x15ff  MOVW   R5, #511               ; 0x1ff
    3 r* r. b  P+ W: v
  60.   0x20000138: 0x1844         ADDS   R4, R0, R15 h% X- r9 V2 [
  61.   0x2000013a: 0x4936         LDR.N  R1, `.text_17`         ; 0x40022010 (1073881104)5 L7 X* u( o( d/ N) H. m% m
  62.   0x2000013c: 0x600d         STR    R5, [R1]: I% A& W) Q: Y, N3 ]+ Z, z
  63.   0x2000013e: 0x2000         MOVS   R0, #0
    # F; Y( I9 O  `$ `  N) V
  64.   0x20000140: 0x684d         LDR    R5, [R1, #0x4]
    * [) {: q  r. D/ W
  65.   0x20000142: 0xf045 0x0501  ORR.W  R5, R5, #1
    0 b, Q& L( Q! C& K% F8 I( T
  66.   0x20000146: 0x604d         STR    R5, [R1, #0x4]" [& ?7 Z* T+ F$ ?2 ~
  67.   0x20000148: 0xe000         B.N    @2000014c
    1 P1 t# X: F; h4 }/ k
  68.                 @2000014a:
    % n1 v- V6 t* P1 l! v; B. K$ P
  69.   0x2000014a: 0x3a08         SUBS   R2, R2, #8* i& s  }# _4 H  V3 q# K
  70.                 @2000014c:' T+ p. \' @# G( C1 d* R, @$ n
  71.   0x2000014c: 0xb162         CBZ    R2, @20000168. v2 A$ V% }& ?3 h
  72.   0x2000014e: 0xe8f3 0x6702  LDRD   R6, R7, [R3], #0x89 U9 n3 B0 {# J) e0 ^! D$ Q: o
  73.   0x20000152: 0xe8e4 0x6702  STRD   R6, R7, [R4], #0x8
    - y. O6 D; k: b% f! k8 ^% N
  74.   0x20000156: 0xbf00         NOP8 R# f! p, q7 J+ f9 R" x
  75.   0x20000158: 0xbf00         NOP/ h7 s0 U* p2 R( ~7 F7 s
  76.                 @2000015a:$ `' l& x# J- p2 x0 t: h2 |) U
  77.   0x2000015a: 0x680d         LDR    R5, [R1]4 e+ M* C; ?8 {
  78.   0x2000015c: 0x03ed         LSLS   R5, R5, #15
      K: B% ^+ E, O
  79.   0x2000015e: 0xd4fc         BMI.N  @2000015a  m; |: N9 t/ l  ^
  80.   0x20000160: 0x680d         LDR    R5, [R1]; p/ S% F, L6 H2 r( X* A
  81.   0x20000162: 0x07ed         LSLS   R5, R5, #31
    7 K) K* {  M. ]
  82.   0x20000164: 0xd4f1         BMI.N  @2000014a: W: q2 ^1 B0 e8 o9 }) c
  83.   0x20000166: 0x2001         MOVS   R0, #1% b5 _! \- u7 |% G5 v  C2 b# U" d
  84.                 @20000168:
    7 F) Z  @" y. O/ x; Q" D3 _
  85.   0x20000168: 0x684a         LDR    R2, [R1, #0x4]/ Z5 @$ x5 O8 ~
  86.   0x2000016a: 0x0852         LSRS   R2, R2, #1
    ; g6 q6 n8 }3 @/ b, ]; _- y
  87.   0x2000016c: 0x0052         LSLS   R2, R2, #19 T' L% W. [& }$ L  C
  88.   0x2000016e: 0x604a         STR    R2, [R1, #0x4]
    & Y$ ^- s7 O) ]) @/ ^
  89.   0x20000170: 0xbdf0         POP    {R4-R7, PC}* \% E' `* @$ o: I  O7 I
  90.                 `.text_6`:& n+ O: i" y: c; v1 E9 O
  91.                 FlashErase:
    / S+ k* c- J! I* h& D5 w; \8 k
  92.   0x20000172: 0x4a28         LDR.N  R2, `.text_17`         ; 0x40022010 (1073881104)5 M9 ^1 ^5 \+ o9 p5 `2 _, }! J
  93.   0x20000174: 0xf240 0x13ff  MOVW   R3, #511               ; 0x1ff
    . \. X" t" n- _. J7 @% }0 x8 Y
  94.   0x20000178: 0x6013         STR    R3, [R2]
    + H9 S8 x9 s% }
  95.   0x2000017a: 0x4601         MOV    R1, R0$ j& `8 S2 X! j* v  D$ ?2 M5 z" f
  96.   0x2000017c: 0x6853         LDR    R3, [R2, #0x4]8 i- m* I* z% I/ ?7 z
  97.   0x2000017e: 0xf36f 0x03cb  BFC    R3, #3, #97 Q! K- ~$ {% Q) |
  98.   0x20000182: 0x6053         STR    R3, [R2, #0x4]
    . f; j/ n" v1 |% E% A8 `2 p5 l2 q
  99.   0x20000184: 0x2000         MOVS   R0, #0
    - k2 S( u: h- e% ^# S$ L1 d
  100.   0x20000186: 0x4b1a         LDR.N  R3, `.text_8`          ; flash_ie
      s7 J, k. _* f$ b4 w
  101.   0x20000188: 0x685b         LDR    R3, [R3, #0x4]
      v( r( G# A; S$ M
  102.   0x2000018a: 0x4299         CMP    R1, R3' P% b+ ]8 U/ J) u
  103.   0x2000018c: 0xd203         BCS.N  @20000196
    % `3 Y3 A, ], n6 d6 |5 x, ]+ A
  104.   0x2000018e: 0x0a09         LSRS   R1, R1, #8
      g6 R" [5 `5 F
  105.   0x20000190: 0xf401 0x61ff  AND.W  R1, R1, #2040          ; 0x7f8
    . p4 z; t6 }: Q, {4 M+ {* k
  106.   0x20000194: 0xe007         B.N    @200001a6# ]% E+ C/ R( J0 ?' t8 ^
  107.                 @20000196:
    # k& H! m, R9 N% h& l3 |1 K
  108.   0x20000196: 0x1ac9         SUBS   R1, R1, R3
    2 [, p1 a) s) M* m. C
  109.   0x20000198: 0x6853         LDR    R3, [R2, #0x4]
    # X! ^4 t0 ]* F4 G2 n9 g! ~. Z3 T! L
  110.   0x2000019a: 0x0a09         LSRS   R1, R1, #8* q# F6 Q0 b+ [1 W) T7 }! Z( j
  111.   0x2000019c: 0xf443 0x6300  ORR.W  R3, R3, #2048          ; 0x8003 v% c0 k& h4 a1 L4 a
  112.   0x200001a0: 0xf401 0x61ff  AND.W  R1, R1, #2040          ; 0x7f8% M+ x' I7 ^1 f
  113.   0x200001a4: 0x6053         STR    R3, [R2, #0x4]6 E, c1 l) A1 B4 g
  114.                 @200001a6:
    ) w' s5 m0 y  l
  115.   0x200001a6: 0xf041 0x0102  ORR.W  R1, R1, #2$ _& X0 R) ^4 [+ t/ Q  T8 {
  116.   0x200001aa: 0x6853         LDR    R3, [R2, #0x4]
    8 h) T: S$ I8 r" N
  117.   0x200001ac: 0x4319         ORRS   R1, R1, R3- y; O$ O0 J; h& S/ I- R
  118.   0x200001ae: 0x6051         STR    R1, [R2, #0x4]
    5 x- j/ d3 V& d( p' Z
  119.   0x200001b0: 0x6851         LDR    R1, [R2, #0x4]1 n3 N. ?* U& U7 a6 ?( x
  120.   0x200001b2: 0xf441 0x3180  ORR.W  R1, R1, #65536         ; 0x10000- S/ h* t. ?/ i, a8 X
  121.   0x200001b6: 0x6051         STR    R1, [R2, #0x4]
    % C' s: \3 h* Z, x
  122.   0x200001b8: 0xbf00         NOP/ ~2 X- p+ S2 x: |
  123.   0x200001ba: 0xbf00         NOP
    5 H* I" }% J$ I9 n3 u
  124.                 @200001bc:* V8 e$ E0 F* s  [$ ^
  125.   0x200001bc: 0x6811         LDR    R1, [R2]
    9 c9 v9 ]- A3 [; D+ R! L
  126.   0x200001be: 0x03c9         LSLS   R1, R1, #15
    ; H% `; n- p2 \" ]4 Z* `9 |
  127.   0x200001c0: 0xd4fc         BMI.N  @200001bc! [# m1 b  I$ j2 `$ d) x
  128.   0x200001c2: 0x6811         LDR    R1, [R2]9 j2 j7 n( ?9 H
  129.   0x200001c4: 0x07c9         LSLS   R1, R1, #31
    - M' q: U7 j5 ]! X5 s
  130.   0x200001c6: 0x6851         LDR    R1, [R2, #0x4]4 R) w* V, ]3 W7 \
  131.   0x200001c8: 0xf021 0x0102  BIC.W  R1, R1, #2
    " U, O7 x# L4 M7 U
  132.   0x200001cc: 0xbf58         IT     PL6 K  v# {4 [/ x: R
  133.   0x200001ce: 0x2001         MOVPL  R0, #13 `5 l* d+ f" {# \# g% N2 K
  134.   0x200001d0: 0x6051         STR    R1, [R2, #0x4]; j" F0 c4 C- e8 B2 Q! ^1 T
  135.   0x200001d2: 0x4770         BX     LR
复制代码
- Q* s( a% B1 c. e* T7 ?
上述通过  
ielfdumparm.exe  FlashSTM32L4xxxRAM48K_DUALBANK.out  -o FlashSTM32L4xxxRAM48K_DUALBANK.ASM --code
命令dump 出来的flash loader 程序,跟预期的保持一致实现了FlashInit/FlashWrite/FlashErase 这组API函数,而且通过反汇编的函数地址信息也可以看出对应的函数的link 地址并不是falsh 区域而是内部RAM 的地址,跟C-SPY 调用flash loader 程序的流程是一致的。

1 `- t1 Y) ^3 x* i

; v4 b; U& T8 w, @: C. S" W
资料分割线
FlashLoaderGuide.ENU.pdf (233.17 KB, 下载次数: 3)
收藏 评论0 发布时间:2022-12-31 12:51

举报

0个回答

所属标签

相似分享

官网相关资源

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