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

STM32L152的IAP移植笔记

[复制链接]
aimejia 发布时间:2018-5-25 11:07
文将针对STML152的IAP移植过程作一个笔记。
' l; H4 i' o8 V2 G' j% j
: r; `1 w4 b0 X8 h) a+ ?: ]首先得下载AN3310的示例代码,地址为:http://www.st.com/content/st_com ... /stsw-stm32075.html
, ~9 ]  ~7 u4 E) ~" U
8 ]: u5 h. \, e" m  m' N& b下载完成后,我们需要做些修改,我们将在NUCLEO-L152RE板子上进行验证测试。, d4 _+ J/ Q6 [# ~& d; |' y
2 i) x" }7 Y, Y8 O
由于NUCLEO-L152RE板子默认MCU是没有外挂晶振的,但可以通过ByPass方式使用ST-LInk的8M晶振,但这里只是作为IAP,且只需要使用到串口,因此可以只使用HSI,于是,在AN3310的工程中打开system_stm32l1xx.c文件找到SystemInit函数,注释掉//SetSysClock();,让系统使用默认的HSI即可。9 \  _1 `. p! x
  1. [cpp] view plain copy5 c! \/ w( i$ c- K: n5 b+ s6 q& j
  2. void SystemInit (void)  
    3 ?/ k( y7 R1 X% _8 K# g
  3. {  
    2 ]( j8 y! ?# i% _/ O
  4.   /*!< Set MSION bit */  
    7 A- l: j( a$ v5 U% R
  5.   RCC->CR |= (uint32_t)0x00000100;  ' y1 ]- t* z7 B* Q# n: u# ]
  6.     v* N* a8 M- @4 }0 p7 W. Q
  7.   /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */  ) f6 y& ^( f$ K$ X" k5 |/ v
  8.   RCC->CFGR &= (uint32_t)0x88FFC00C;  
    7 H* c! f6 z6 m( |$ `0 V
  9.   
    3 {% l6 |7 @8 A" I8 x
  10.   /*!< Reset HSION, HSEON, CSSON and PLLON bits */  ; U1 K* y7 {/ O# d
  11.   RCC->CR &= (uint32_t)0xEEFEFFFE;  2 [2 n9 ]" G, \" D0 N1 [
  12.   ! d8 A( D7 Q/ m0 D  M4 X) P% s  ~
  13.   /*!< Reset HSEBYP bit */  1 r* l  @" I' ]0 D% z
  14.   RCC->CR &= (uint32_t)0xFFFBFFFF;  
    ; ~; O" |. \* `/ Q" |* S5 }& X) D: P
  15.   : n+ v( P( n3 N
  16.   /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */  
    ' [- p& m  A- j1 ^6 j
  17.   RCC->CFGR &= (uint32_t)0xFF02FFFF;  
    , V1 `/ K5 h( r0 I+ ~$ B) s; U7 m
  18.   1 s  A: s" ~; e# L
  19.   /*!< Disable all interrupts */  8 q' ?7 m' ?2 R" v3 `
  20.   RCC->CIR = 0x00000000;  & b' X; G) M2 M
  21.   
    $ L( I: p) V; H/ G; g: y6 F1 D
  22. #ifdef DATA_IN_ExtSRAM  
    - X  \# B7 M$ u7 R
  23.   SystemInit_ExtMemCtl();  : |* f( o- o1 x/ e( m
  24. #endif /* DATA_IN_ExtSRAM */  , Q& X  ^' p8 r; d- @( S
  25.   " K6 W* t8 S7 H; n
  26.   /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */  
    # s7 ?7 d* a3 m' N
  27.   //SetSysClock();  
    + I6 k8 c' M0 S5 B6 W: c; O/ ^
  28.   9 M! N+ d/ M* H$ M, F
  29. #ifdef VECT_TAB_SRAM  ) f; [0 c6 t7 ~$ t* H  X- o, D
  30.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */  
    1 e2 w' E2 Q" @; m: o1 q# i, N
  31. #else  $ b9 k9 F& w. g- F: V8 e% L
  32.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */  9 F3 H: J" J, w0 `' |( o- W- ]5 A
  33. #endif  
    6 z$ L. k$ d) O1 L; }/ f  z. X' A
  34. }  
复制代码
然后修改man.c文件中的main函数,注释掉一些按键,让程序默认进入到升级模式:
) \6 k; k' G  c& Z" U
5 M* ]' o1 C4 [! h, }
  1. [cpp] view plain copy/ h( y" e# o+ T( l( S
  2. int main(void)  
    5 \' F# C8 F/ x6 }# C" O
  3. {  
    ; {7 S# l: l) z* L& s9 d1 {
  4.   /* Unlock the Flash Program Erase controller */  ( f, A, _& p1 u
  5.   FLASH_If_Init();    M2 X3 o& p; x0 P+ [, M
  6.   
    & f& B- \# K7 `- W
  7.   /* Initialize Key Button mounted on STM32L15xx-EVAL board */  
      i& [0 U0 T' u8 ?4 e! @
  8.   //STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);  
    # ~: [* [7 h$ ?- b& u9 T, j. v
  9.   
    ' f, X. F5 r) C+ ~; H' L% m+ y
  10.   /* Test if Key push-button on STM32L15xx-EVAL Board is pressed */  9 Z/ K. M9 L) W* R+ c) K: ^7 b
  11.   //if (STM_EVAL_PBGetState(BUTTON_KEY) != 0x00)  - Y  b) B) z$ r! ?
  12.   {  
    ' F+ @" Y6 G# f' }( _* D) `2 L# x3 x
  13.     /* Execute the IAP driver in order to reprogram the Flash */  2 h- f4 f5 v8 E2 p0 D$ D
  14.     IAP_Init();  1 ?! @# ~. p) O% s
  15.     /* Display main menu */  8 N7 ?5 l9 B: |
  16.     Main_Menu ();  9 A6 p2 H7 i6 F# @  e8 r
  17.   }  
    7 s) ?' I' o( d- L
  18. #if 0  
    . Q% z( W; {5 v0 S) z0 V! \
  19.   /* Keep the user application running */  7 j4 ]1 y0 M! q" i- I- h
  20.   else  5 t" k$ u: v5 [& q" J: M9 ~  d) [
  21.   {  $ o5 @) H3 E8 m- @
  22.     /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */  
    0 x+ O& c" K$ I5 K* i) `- j
  23.     if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)  
      ]% z; H: V  M! a7 w9 r
  24.     {  * R& V, T. [7 p1 a9 o: b# u5 g: V* }
  25.       /* Jump to user application */  
    * _& q9 S* R" B/ |$ H
  26.       JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);  
    3 z. Y  O2 M+ \3 |
  27.       Jump_To_Application = (pFunction) JumpAddress;  
    : \' e6 w* L+ j" g& R5 N  d; M
  28.       /* Initialize user application's Stack Pointer */  
    : y. V7 T9 e3 ~* ~
  29.       __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);  
    # h8 S, X9 Z/ E( M* M
  30.       Jump_To_Application();  9 n/ M( y/ o: f1 \) W3 D
  31.     }  ) f$ j, D2 K# u4 r
  32.   }  
    + |. [" j- [; W" R7 d2 j' X
  33. #endif  
    / c0 P6 U: Y* q" K3 [3 i
  34.   while (1)  
    8 ]& H$ x. F- a0 E& T+ T
  35.   {}  1 |% X0 h) W! b7 _- W, i3 ]5 ?
  36. }  
    - C8 L+ a: P1 G2 q% ^7 E
复制代码
由于NUCLEO板子默认使用的是USART2,因此需要修改使用的串口:
! N$ {8 ], T( x, T. T0 _, n+ f
  1. [cpp] view plain copy
    & w3 Y3 J& Q; s4 E# y
  2. void IAP_Init(void)  
    7 p% O, C( }5 y) f; d6 ~
  3. {  
    3 R! Q8 E' e: W  Q8 h! V8 h. U, a- I
  4. USART_InitTypeDef USART_InitStructure;  3 T3 ~3 G8 A8 J8 C" V* S
  5.   /* USART resources configuration (Clock, GPIO pins and USART registers) ----*/  4 h% K+ w/ h2 y7 n
  6.   /* USART configured as follow: % M6 s- ^# H- ?2 W% ~; J
  7.         - BaudRate = 115200 baud
    . [0 a3 C* c) o" A# s  H
  8.         - Word Length = 8 Bits
    6 _( U8 N# f; @* w7 j
  9.         - One Stop Bit ) l2 A' S" T" J+ x  N8 Q# d
  10.         - No parity
    7 w: ^- V) X% h
  11.         - Hardware flow control disabled (RTS and CTS signals)
    $ Y) K1 ?# ?! m* m5 q3 c/ Q# a. w
  12.         - Receive and transmit enabled
    % R; c% N+ j0 U8 ^" ]" x' l6 j# E
  13.   */  2 D4 Z6 z- P' ~  J! Z1 Z0 n3 I
  14.   USART_InitStructure.USART_BaudRate = 115200;  : C* }7 d8 ?6 Z& z! u
  15.   USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
    & N, D! T) I, c2 A. f, |6 u, f
  16.   USART_InitStructure.USART_StopBits = USART_StopBits_1;  
    0 p7 f; m% n. P# R& l6 G
  17.   USART_InitStructure.USART_Parity = USART_Parity_No;  
      L1 Z! [$ q$ d! r+ m# ]7 z: U
  18.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
    9 t4 A$ _/ s! ~# E# J
  19.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  
    % [, k% P, G; H+ T
  20.   
    / G' r" i9 P. N' `& h0 D
  21.   //STM_EVAL_COMInit(COM2, &USART_InitStructure);  , }0 n& C0 P7 [, B
  22.   USART2_Init(&USART_InitStructure);  
    - v8 u& F% c2 u$ R1 e0 H
  23. }  
    4 I, f7 g0 u7 M# N. N
  24. & ]6 y2 q; J, ^$ y3 j3 e) W! S+ s( J7 `
  25. USART2_Init()函数为新添加的串口初始化函数,其定义如下:
    3 W( u2 [. u8 D/ e2 {2 j) O% ~
  26. . m" o1 q) x! D9 y9 s! @$ n
  27. [cpp] view plain copy$ _- w  J% q" L
  28. void USART2_Init(USART_InitTypeDef* USART_InitStruct)  
    . B8 m2 w% k) h" l/ U: \
  29. {  4 j, F7 Y2 Q0 D% S9 y; ]8 ?+ r
  30.   GPIO_InitTypeDef GPIO_InitStructure;  9 {4 }! \! j& z& I6 c+ Q( \2 A
  31.   
    1 x0 o7 a, T: ^4 c: ]2 Y
  32.   /* Enable GPIO clock */  ! S; N  _* d- T; t, M
  33.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  
    9 u7 f, k4 k' C) }  h3 J1 H
  34.   + {- V0 o. i4 `6 a1 u( e
  35.   /* Enable UART clock */  " u% c0 L. ]8 T0 ~4 T0 H
  36.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  ' O3 E6 q; G, X4 a
  37.   # y  Y% W& }& D* M- f8 M
  38.   /* Connect PXx to USARTx_Tx */  : O! k* }" N  R" k( a- O4 f
  39.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);  
    8 L2 i/ p8 H+ {; p& c1 d  q
  40.   4 W' m: |$ [8 p2 ^, ]* K+ N
  41.   /* Connect PXx to USARTx_Rx */  
    6 u! j' A# ]7 S% M8 x! ^" W
  42.   GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);  * l0 I5 q  o  J3 Z1 W6 m9 E! i
  43.   0 c0 O2 G, N2 X
  44.   /* Configure USART Tx as alternate function push-pull */  " s) t1 B  k+ d6 }7 ^
  45.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;  
    5 n6 Z& |; W2 N: I7 \+ t/ L
  46.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  
    , k( b7 J; ^+ a; ^( f
  47.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;  7 t, S0 N* C; m4 D- O
  48.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  $ \* D5 ?3 P  Y# o" [
  49.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
    # I7 E0 Z& g# N# }% {- v
  50.   GPIO_Init(GPIOA, &GPIO_InitStructure);  ' M2 t' \4 v0 T* [
  51.   
    , F  c$ ?* c* p
  52.   /* Configure USART Rx as alternate function push-pull */  7 z6 a; J5 d9 O( S
  53.   //GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM];  
      Y" M! _7 @6 P5 A, O' f
  54.   //GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure);  2 l$ b6 P  B; p0 J) A6 x
  55.   
    , ?+ u# |0 R; [; n+ p2 @% p
  56.   /* USART configuration */  * ?! p+ I9 ]6 X% b& k8 R9 w) b" V
  57.   USART_Init(USART2, USART_InitStruct);  
    # r& O, A$ @$ C5 R
  58.   
    ( F: P) M  @  |( o. R
  59.   /* Enable USART */  
    + y9 O# y% s" ?( r3 n( b8 _
  60.   USART_Cmd(USART2, ENABLE);  - s$ g, Y7 d( @& `
  61. }  
复制代码
接下来需要修改程序中使用到的打印函数:
( T* r9 S8 B2 P6 I
  1. [cpp] view plain copy
    ! Q* o* }! ~) E( ^3 B
  2. void SerialPutChar(uint8_t c)  
    7 L( d5 v0 F+ l% i
  3. {  
    1 C# k  O, |4 x' v
  4.   USART_SendData(USART2, c);  # n: e: M- ^# U! Z# S# S
  5.   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)  8 [) _6 }  F' a, ?
  6.   {  
    9 \6 i8 X5 u5 w
  7.   }  
    . u* F1 u* B  m4 `
  8. }  
      H5 |. m+ [9 O3 J- V9 O

  9. ) r+ ~$ V8 B. B& p. r
  10. . l& i. H' w# w& i# S3 Z
  11. [cpp] view plain copy( ]4 T! I! B( \& w7 o4 V9 K- s
  12. uint32_t SerialKeyPressed(uint8_t *key)  ! C% N' U4 v0 D& \1 ^3 Y7 ?
  13. {  1 \) E; b; G# I3 t7 e) G1 @- Q
  14.   ' P1 q2 _' E% @7 |8 n1 j, H; h8 c
  15.   if ( USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)  " Z! C/ X* t/ j6 U8 ^5 N5 a% O
  16.   {  
    6 Y1 S4 c6 A: R" j$ N
  17.     *key = (uint8_t)USART2->DR;  
      j$ X2 y/ y5 y; y
  18.     return 1;  4 t( W: Y$ ~4 G) n  ^$ ]
  19.   }  
    ; r! J* V8 P! x+ k! G
  20.   else  
    4 Z7 U! Z' i. S) c7 i1 O6 o8 ]2 O
  21.   {  
    ( E1 s( g9 e. K: z' X, N
  22.     return 0;  
    2 G/ M% T9 T: F% O, o+ _5 F
  23.   }  6 \( Y( x: e7 s1 F& N
  24. }  
    3 k2 ~  W2 i% B
复制代码
基本上就移植好了,编译烧录进NUCLEO板中运行。
4 Z) E$ [) k/ C# o7 _  ?& U9 ~6 [3 w% k6 O6 b' E
接下来需要找一个PC端软件超级终端。$ S* S( p( ?5 Y# \+ b+ K
除了IAP程序,我们还得准备APP程序,由于IAP支持烧录的是BIN文件,因此,我们得生成BIN文件,HEX是不行的。! Q0 }' z2 c. W8 @* w, I
. p0 w! W) I& C1 D$ q) ~
在APP工程中我们得注意几项内容,以IAR为例:0 g1 \- |' f# v9 h

% ?  E5 m, T( k; x4 ]8 ~$ p1 在option->Linker下:
2 K) L9 M) g& Z" v) t% N  D% m0 R
  config->Edit..--->Vector Table 的起始地址改为:0x08003000# _( @6 Z# A$ y+ |% w

2 q9 r- l3 f+ D) W4 h0 W  ---->Memory Regions->ROM改为:0x08003000
; u) Y" ^9 w) d) a& K. {+ p- v% s0 t! k" S) k& V( I- c2 e
2 option->Output Converter->修改生成BIN文件
6 x5 |- @0 K) S* h* r* R" V
* D1 R1 q8 ]/ [/ k: j3 i" Y& x3  sysytem_stm32l1xx.c文件下
0 Y6 t! ~, R/ F# ?8 m+ v* c
9 q# W8 M1 ]0 m  E5 X8 S 找到宏定义
+ \7 h* i+ Q9 M8 Y4 P' E3 N7 l, W  x, V7 x% {# `* p% G# [
#define VECT_TAB_OFFSET  0x30000 T* B! {- ?: x) c9 W) Y  Y
0 K2 I: m( q) C$ j' l
偏移位置必须改为0x3000
  \% h1 R1 X8 `6 t) u- k4 _3 F1 j1 d: n# F" t  d. [
到此基本可以了,APP就这样。, n! [- s# v0 m- m& y9 `

9 I6 g. r6 j0 z- v* W6 B最后就是测试了。! c, ^$ E9 b4 h6 t
) q/ C1 w  e2 I
测试:. E$ C! c* n" e& K3 N; a
* {' U7 p( {6 Q
首先得将IAP烧录进MCU,然后再通过IAP烧录APP。2 _( U' b! X7 n8 Y, L
9 t* r. J* \; c* k' Q
通过IAP烧录APP过程如下:
1 N6 d9 ^& P* f7 I  F, z( `1 [; B/ C: u( {+ [. w
打开超级终端,连接上串口,有如下界面:" x" S) b$ u1 g
" |8 Z9 `& y  x
波特率:115200 data bis:8 parity:none stop bits:1 Flow control:none
& O% C; F: w" \% M
- m  W( l  _& Q! n: i9 P. f 1.png
+ B0 t3 n# _& C" `8 Y- c1 a1 h; |: J5 t4 D8 u
通过键盘输入1:# p& L$ R( h; b
+ ^& L* ?4 [" l) k% `
2.png
: f0 G2 d; v; V$ H  U' I$ q7 U, h* x  Y+ T7 q$ ?4 \* s( F
从菜单transfer->Send file打开如下界面,输入APP的BIN文件路径,并使用Ymodem传输协议,如下图:# d' p: C) u* h( H# q8 l

) ^) a0 |  f# J1 F' [/ t( c 3.png , S6 z* [. r0 ]9 J3 l$ J# i' G/ h/ M  I
' w6 O3 n. q* t  e4 j
点击Send,开始烧录。。。  p! W: v$ e3 h. ]1 b8 s# D; w: V
; V4 J% I0 F7 p% h
4.png 9 a  Y6 B  y: e0 J* R

* F) A3 W$ `6 F传输结束后,按下3,运行APP程序,至此,整个IAP与APP都可以正常工作了。- d1 I0 i; I. x8 c

# W: q+ `% X) {8 v( f6 U4 w# {  t( y7 N/ G结束语:
; }# c: D; t) B7 t0 W4 r& H0 z6 j& r, K# g
这个只是个示例,实际IAP是还需要修改的,得判断是进行升级模式还是直接跳过进入APP,这个就需要看设计如何了。  _( s2 O9 _% R

% f2 b/ a) c! j& S3 R9 D: F6 N0 x+ C5 s9 |

; b/ c6 q4 }* e8 w2 G9 K  Q5 v+ H  @: W+ V1 e- r% D
转载自flydream0( B, d& z6 k2 g6 |0 B  h" _
  g6 _: [+ W; u( I3 H1 ?* r- J
0 v7 o/ k" A9 C. r8 H: M9 b2 F
! [. N# a: p4 E# B* h
收藏 评论0 发布时间:2018-5-25 11:07

举报

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