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

STM32L152的IAP移植笔记

[复制链接]
aimejia 发布时间:2018-5-25 11:07
文将针对STML152的IAP移植过程作一个笔记。
& K# T7 g4 p: o4 w% U
7 k, V! z+ E" C, Q* J( ^" A首先得下载AN3310的示例代码,地址为:http://www.st.com/content/st_com ... /stsw-stm32075.html7 K1 f/ l0 E# d( Q) v; e; l
% J3 d# Z, S; _5 j% t9 t' `! g
下载完成后,我们需要做些修改,我们将在NUCLEO-L152RE板子上进行验证测试。2 i, N! e1 F, m0 U$ [/ K$ ]
/ M; Z( F  i0 ^4 }% ?6 ~
由于NUCLEO-L152RE板子默认MCU是没有外挂晶振的,但可以通过ByPass方式使用ST-LInk的8M晶振,但这里只是作为IAP,且只需要使用到串口,因此可以只使用HSI,于是,在AN3310的工程中打开system_stm32l1xx.c文件找到SystemInit函数,注释掉//SetSysClock();,让系统使用默认的HSI即可。6 R6 [/ O: v/ o/ J* O* `) n
  1. [cpp] view plain copy
    ; [8 }, t$ X$ k9 `9 ^
  2. void SystemInit (void)  
    * M4 [4 P- s; S. v% y$ B
  3. {  9 O" \' ]" `7 M' C$ _
  4.   /*!< Set MSION bit */  # Y1 J2 l7 g, F* j$ e% v
  5.   RCC->CR |= (uint32_t)0x00000100;  
    5 Q  I9 t2 j- r
  6.   ! X2 g$ ^! L' b# D. f7 P: E( {
  7.   /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */  
    9 u, d! ]& c1 T1 u% S
  8.   RCC->CFGR &= (uint32_t)0x88FFC00C;  
    + O* r/ [2 k* d! |
  9.   $ g/ J5 B; d) n* q) A4 z( }6 Y5 Q
  10.   /*!< Reset HSION, HSEON, CSSON and PLLON bits */  0 [7 Q8 H) _+ e* U; Q  _
  11.   RCC->CR &= (uint32_t)0xEEFEFFFE;  
    3 f  @0 n) m- F- w3 ~( _8 T
  12.   
    1 b: Q9 {) U4 n) p
  13.   /*!< Reset HSEBYP bit */  7 V, e8 d4 m4 B/ W/ Z
  14.   RCC->CR &= (uint32_t)0xFFFBFFFF;  
    : z4 L0 t+ H( u- l0 u1 _( R8 ]7 g: ?/ C
  15.   ( z! l8 h3 L. O/ U' [' w
  16.   /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */  ) b5 g+ @6 A8 T3 x) q7 e! E9 V
  17.   RCC->CFGR &= (uint32_t)0xFF02FFFF;  , X- }) S7 C8 \3 P
  18.   
    + g* @: \4 D. K2 k( E; Z
  19.   /*!< Disable all interrupts */  & _' n+ F' T+ E2 n
  20.   RCC->CIR = 0x00000000;  ) Y# G% W5 E, \! K: X2 C
  21.   
    2 [, N* M8 {, i& m6 ~) n
  22. #ifdef DATA_IN_ExtSRAM  4 C1 [: K$ T5 p& _' s0 ?& O
  23.   SystemInit_ExtMemCtl();  
    2 P6 n  n) f- _$ ~
  24. #endif /* DATA_IN_ExtSRAM */  
    ) V4 P) k) M+ B! R% D! u& l
  25.   + D) G+ x- B. F
  26.   /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */  ! ~8 }2 i; _! C" y2 o
  27.   //SetSysClock();  
    5 ^% `& W# G( f+ J
  28.   8 G) L- S' B* J: t6 k* b
  29. #ifdef VECT_TAB_SRAM  * G! X( }2 K9 a: s# g" I
  30.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */  
    # X- Z" h3 E3 v5 U7 M2 A% [; D( `
  31. #else  
    - i! r9 F- y8 y4 f1 I1 ?- o
  32.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */  
    # n  M# g5 J8 M
  33. #endif  
    # [$ ^! `" D  q4 n0 g+ J+ g# B
  34. }  
复制代码
然后修改man.c文件中的main函数,注释掉一些按键,让程序默认进入到升级模式:
" T' z( N) g, E5 d. W- K) d# A* x; }1 m) @4 a) Y: P7 Y9 R4 G
  1. [cpp] view plain copy
    5 N' ?' q4 ]; U2 Z
  2. int main(void)  
    1 o# |) g4 D) W: D$ a& P7 B# [9 h
  3. {  6 C2 p. x: c" B& e
  4.   /* Unlock the Flash Program Erase controller */  / o7 h/ B) n/ K  I8 f
  5.   FLASH_If_Init();  
    - j! _& A& I3 d4 `* o4 q8 R' \
  6.   ; I& G$ a. Q2 n' V& d$ U
  7.   /* Initialize Key Button mounted on STM32L15xx-EVAL board */  & m/ u. @" Q- r) B
  8.   //STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);  $ R! O; @' M3 m* y, z6 a# M
  9.   
    $ W: B8 j4 g; p/ j5 ~/ {% Z+ O
  10.   /* Test if Key push-button on STM32L15xx-EVAL Board is pressed */  
    & Z. B; j2 ]* j! S
  11.   //if (STM_EVAL_PBGetState(BUTTON_KEY) != 0x00)  5 S- ]0 R7 O5 z: \
  12.   {  
    ' X: |1 m: W" }2 j$ Q
  13.     /* Execute the IAP driver in order to reprogram the Flash */  . V$ A0 p" e8 X5 Y1 `- G& w& `5 |
  14.     IAP_Init();  
    & o: N# C8 Z# d
  15.     /* Display main menu */  2 ]- Z$ @% `  T7 f; L5 I, t
  16.     Main_Menu ();  : n: g( n8 J4 B
  17.   }  
    # e4 r+ E  @$ |  {, Q
  18. #if 0  $ J- D, H' q/ C6 |" M+ L
  19.   /* Keep the user application running */  0 V* U6 r4 ?; \* r; ^! U7 i
  20.   else  4 m8 n0 E0 ^1 o8 Q$ g$ }1 P
  21.   {  
    . q2 b2 N+ t& ~) J4 w; L% ?- \
  22.     /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */  $ x- r! C. `# D4 A/ Q) I
  23.     if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)  : q9 H& _6 w! c! F' B) X
  24.     {  
    * h" D/ d! Y. Y( o) I
  25.       /* Jump to user application */  + A) ?5 F- [% j4 l" R7 F
  26.       JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);  
    0 `5 p0 r+ n5 L0 ~: [
  27.       Jump_To_Application = (pFunction) JumpAddress;  3 A# ]3 S# t5 t' ]
  28.       /* Initialize user application's Stack Pointer */    ?5 L$ U! z) T( ^$ A$ L' V
  29.       __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);  8 [5 C: r, q- @9 X' |; M
  30.       Jump_To_Application();  
    ) _$ G1 S  Z3 Q$ t, T( F3 [4 X
  31.     }  6 p. A# S# s' M* p- R- w
  32.   }  8 m& Z9 H& t% |3 c/ n0 Y
  33. #endif  9 {8 p( [/ Z7 M) ?3 m4 [
  34.   while (1)  
    . Q# V! M. ]) q& l. ]6 \0 s  K
  35.   {}  1 i  q0 M! [+ q$ {) j; Q0 L
  36. }  1 H9 `8 R. [  ]# s) b0 O! I
复制代码
由于NUCLEO板子默认使用的是USART2,因此需要修改使用的串口:( b6 N5 }* k$ I
  1. [cpp] view plain copy
    , `! i4 }8 `7 [  ?7 W+ N
  2. void IAP_Init(void)  
    8 B9 i( U% L3 S6 ~' D
  3. {  
    + s3 I1 M1 k; v! z* k. s
  4. USART_InitTypeDef USART_InitStructure;  
    0 p9 k( N9 J! R! A
  5.   /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/  + \  g/ u) f5 F7 n/ K; L2 g7 r# ]
  6.   /* USART configured as follow:
    2 ^" C/ w4 D0 A
  7.         - BaudRate = 115200 baud 9 u4 d4 W- e5 w' g9 o
  8.         - Word Length = 8 Bits ) t( Y- l" z2 l& N/ R
  9.         - One Stop Bit
    / u1 ~$ ^# M) U$ j/ Z
  10.         - No parity & |5 F  \+ w  F. \
  11.         - Hardware flow control disabled (RTS and CTS signals)
    % a5 X% N1 O& o9 I6 i, q
  12.         - Receive and transmit enabled
    + N/ s9 c! {. s- ]! e. b+ [  q4 M
  13.   */  
    / N( A+ k& [* J6 `
  14.   USART_InitStructure.USART_BaudRate = 115200;  
    1 z$ f2 K( w2 D( X* Q- s
  15.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
      V2 d: ?: z" t& x
  16.   USART_InitStructure.USART_StopBits = USART_StopBits_1;  
    % S& V, l3 B' f" @! b' I4 B
  17.   USART_InitStructure.USART_Parity = USART_Parity_No;  . I, A1 h5 x. Q
  18.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
    9 m, y5 O: G! W1 p6 L( t6 O5 U
  19.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  " g( g; a5 P4 \8 g  h
  20.   
    % C4 q- C4 V$ v* G; d3 m
  21.   //STM_EVAL_COMInit(COM2, &USART_InitStructure);  
      ^3 @' p. S+ m
  22.   USART2_Init(&USART_InitStructure);  
    + {7 Y! G* V! D$ ^- w
  23. }  
    1 k# e- H: O) [- I7 {. x( a! h2 P
  24. ! V) r& q$ Y* t6 |' o, A
  25. USART2_Init()函数为新添加的串口初始化函数,其定义如下:+ S- p! R7 K- l. G

  26. ' j5 }# {5 R" N! v; V
  27. [cpp] view plain copy. ?+ M" Y+ u/ ?& ]
  28. void USART2_Init(USART_InitTypeDef* USART_InitStruct)  5 J2 l3 D+ a0 c- L, v2 N, B& [4 P. x
  29. {  * n) T# E7 |0 H$ T
  30.   GPIO_InitTypeDef GPIO_InitStructure;  5 r8 V4 Z# O& ]
  31.   
    ; K; E) x4 X4 s! i8 H5 S. ~
  32.   /* Enable GPIO clock */  
    * O; O8 I5 h( e) g2 ?: }  W9 x( v$ k
  33.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  ; T0 k7 z/ \5 m2 P0 u$ n
  34.   8 T( E6 {, c9 f, N8 P
  35.   /* Enable UART clock */  
    " b" }1 T! h8 Y$ m
  36.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  5 v: G$ A- u2 U, M
  37.   
    ! y5 S* y) U9 Z5 |' v" k
  38.   /* Connect PXx to USARTx_Tx */  * g4 Z3 ~6 T* c0 K/ O
  39.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);  
    8 q- C7 ~4 H1 B) M0 S5 Y
  40.   0 D  y/ o* ^, N. ?
  41.   /* Connect PXx to USARTx_Rx */  3 U5 A) J2 E+ K- N' W$ a" W
  42.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);  
    ; f  ?& \5 \( V' F( w2 b, R5 {
  43.   
    " _3 }9 y6 ~3 d% `
  44.   /* Configure USART Tx as alternate function push-pull */  
    $ h7 }7 b- G- Y0 r+ Y
  45.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;  & W9 z; a, k9 Y- @! J8 y( Q
  46.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  
    4 T& p/ p5 f( L2 _. a" N6 V+ H" f
  47.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;  
    + Q+ A5 y; _. ~) P+ c' q, ]
  48.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  
    ! |; e7 b! p( s, ?; |
  49.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
    0 P- A) K1 \. T/ K
  50.   GPIO_Init(GPIOA, &GPIO_InitStructure);  
    2 A. k5 Z$ B. H0 H. {. f: U
  51.   4 |* A* s# K$ Y5 G) a& F
  52.   /* Configure USART Rx as alternate function push-pull */  " Q2 _4 l! w1 u2 G9 m) P0 {
  53.   //GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM];  . `8 H) a" j$ O) U6 [  K+ C5 ]
  54.   //GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure);  
    / l, k9 y/ k$ J" n$ B* I, I, {
  55.   
    ( `7 T9 V4 o, ^/ `- R
  56.   /* USART configuration */  2 o$ S9 x8 C5 v# a
  57.   USART_Init(USART2, USART_InitStruct);    _; r) j1 W! `& m
  58.   
    & C$ O& K' g( p/ _; t( \9 i
  59.   /* Enable USART */  ) F; U& M1 t4 y" c) N
  60.   USART_Cmd(USART2, ENABLE);  
    1 F) J% |1 t# r. P+ p# C' T& w2 g
  61. }  
复制代码
接下来需要修改程序中使用到的打印函数:
  i, Y! V: K1 Q$ {- t, ?' G- u3 @4 c
  1. [cpp] view plain copy
    ! w4 B: p. a. G% a" M/ [# w
  2. void SerialPutChar(uint8_t c)  + H  F: Y: x  b8 k9 i% U9 c
  3. {  ) Z0 c# ?0 P5 u' u2 \
  4.   USART_SendData(USART2, c);  & `+ |" s" @: s& m8 o. J- B  _- h
  5.   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)  
    " h- ^% Y; B6 ]' F1 j) w
  6.   {  1 T$ N; W0 I& I% g
  7.   }  2 I5 U7 _1 }% ~( \8 u, F- q
  8. }  
    5 ?; [, L* \- m: r

  9. 8 x! K) B/ ^% Q. t

  10. 9 A  p! W) r. `/ q7 ^
  11. [cpp] view plain copy- S! E7 I" f' `4 X
  12. uint32_t SerialKeyPressed(uint8_t *key)  
    % r& {! v3 y  [
  13. {  . U3 e+ \; o& J) _) l
  14.   * z; N* _' K9 r2 R6 O+ r. H
  15.   if ( USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)  / `- i/ ^, E; @. b3 N# Z6 W
  16.   {  7 y& h1 Q) t8 R
  17.     *key = (uint8_t)USART2->DR;  $ T' G9 b* y0 w! F, A1 o
  18.     return 1;  
    % a' x4 j7 N9 @1 e
  19.   }  
    3 G$ p: G  A) a# j" `: O
  20.   else  
    4 f9 d* E) f0 a( `# g7 z" g
  21.   {  ) s" P$ R1 Y* C+ F+ f
  22.     return 0;  
    9 b! }# c; `" ]4 b4 D# n- c4 W
  23.   }  " {3 w9 Z( t" Z  T# F8 ?9 I# U
  24. }  
    ! c0 m! g5 I/ y
复制代码
基本上就移植好了,编译烧录进NUCLEO板中运行。4 ?! ?5 T0 U7 N* Q8 o8 K" k5 {
% |# K+ F( g+ q" V# k
接下来需要找一个PC端软件超级终端。- |4 [$ u% |4 Y( S3 f
除了IAP程序,我们还得准备APP程序,由于IAP支持烧录的是BIN文件,因此,我们得生成BIN文件,HEX是不行的。
% L5 o( [' K5 P" ^/ m( {& q6 x4 e! V7 g+ y  X4 E2 u  {$ `
在APP工程中我们得注意几项内容,以IAR为例:3 j& t, C2 i7 b- H' i
! F7 o( u$ }  x4 g' u9 x$ S
1 在option->Linker下:! {3 O  u+ e/ g

, u! u# }7 F! u+ z  config->Edit..--->Vector Table 的起始地址改为:0x08003000
: p4 X3 f: e& Q& _. y  M, r; \5 f- ^8 X8 r) N1 x9 |. Y. g6 A
  ---->Memory Regions->ROM改为:0x08003000
. ]1 O4 a# `7 Y+ ?2 ]4 [7 v# F$ C1 c" s6 m! G1 L
2 option->Output Converter->修改生成BIN文件
: g& c/ B! F9 n+ H) G' ]5 a" h0 R/ U4 A3 `# r, {3 `
3  sysytem_stm32l1xx.c文件下
# F. J$ @2 F# o
+ N" E* V5 T8 [$ |' j7 c4 z 找到宏定义1 L5 P% b9 ?) [
) X. N  r( i# p" Z+ d9 P. h9 B- ^
#define VECT_TAB_OFFSET  0x30007 |3 W- [, G0 [9 _9 A9 d
6 t+ y6 e' R5 q
偏移位置必须改为0x3000+ A  M( B9 n% p! I
! e8 U; C1 T6 Q( V$ F( X
到此基本可以了,APP就这样。: o0 ]7 g+ w8 L3 Q; R

. M" h8 l! Y& {% @& W  ^" F" ~& [最后就是测试了。* E( _. ]8 F& v! T2 J* U) }
/ N1 C: N( r* D4 n
测试:
5 P7 A2 F/ y  p, S* w9 A8 f9 j# H: q
  Q" N3 \* J7 U2 q6 t! j" C首先得将IAP烧录进MCU,然后再通过IAP烧录APP。1 s! I4 f5 n. J, j% T: v, X! {
2 t  S1 n  a/ d% H; i5 J
通过IAP烧录APP过程如下:+ T: q0 S' Z* G$ L

: W% z, y8 \. P打开超级终端,连接上串口,有如下界面:. J0 d) e6 B9 o( u& h$ d# m
, |6 Q& X, m3 w5 P
波特率:115200 data bis:8 parity:none stop bits:1 Flow control:none- d# N: N! T+ `: L0 I3 v- ?
% @. T5 u- j3 J+ ]/ u
1.png
8 f- h4 K* h* E
$ G! d8 ~- N5 D9 j通过键盘输入1:
! I, |! [* X( w# a
) C; o) S% v7 w; J% Y: e 2.png : u6 ?  \; \: K2 B  q
' S0 N  I5 Z3 @5 D6 @! U
从菜单transfer->Send file打开如下界面,输入APP的BIN文件路径,并使用Ymodem传输协议,如下图:
5 K3 a; }" V4 c( }; i! ~7 F6 S& J0 T
, z6 U( e6 x8 V7 J) b  \# I# j2 w 3.png ! A  A$ x; E" C& }$ @. W9 }

8 R: p9 K5 ]! ^$ j6 e点击Send,开始烧录。。。
* x$ G' N8 q8 F! t& Q4 s# X
- Y  c( A* K$ Y: _8 I$ E$ r 4.png 7 I& K& r; Y! j$ e1 \0 f/ w" _2 d; s
! i3 L9 B$ m5 G1 g
传输结束后,按下3,运行APP程序,至此,整个IAP与APP都可以正常工作了。% G; r0 U% P6 `# u

/ C( O& r4 J. n4 j& i+ i; O  L结束语:
) g& b1 d7 O# o' H# m5 A9 n9 Q' ?, }& |; C8 q% d" H  |' X( ]4 K
这个只是个示例,实际IAP是还需要修改的,得判断是进行升级模式还是直接跳过进入APP,这个就需要看设计如何了。$ Z1 }6 \( A. Q, T1 {- q( K

7 _, J$ x4 z0 {8 t- u4 H
! E1 F: _  P- U% V( R( E% ?0 g  h$ u3 C8 K) k; |$ I$ P
! U$ Y/ n  D0 x4 z
转载自flydream05 o  E/ L( z4 d+ {
5 ^) ?% {. |0 I7 T" p1 G, \

7 j. Z' U! `! i, Z0 g+ F# i$ H
% d: t) N+ m1 [6 m9 \
收藏 评论0 发布时间:2018-5-25 11:07

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版