请选择 进入手机版 | 继续访问电脑版

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

STM32 CUbeIDE 使用Ymodem协议进行串口IAP升级

[复制链接]
STMCU-管管 发布时间:2020-9-21 10:16

学习了一下使用Ymodem协议串口IAP程序升级的功能,移植的是ST的工程文件。附上下载链接http://www.st.com/content/st_com/en/search.html#q=IAP-t=tools-page=1;ST官网提供的各种IAP,其方法和原理其实都类似:就是将程序文件(二进制文件)写入FLASH。


' F: Q" B) I$ o6 V$ w

: z( E: p. ~& J- Z

1_meitu_1.jpg
( l, k  g. \- ]- V5 X! S4 x7 e* s
# z: o$ @. |* z6 j' L5 [

1、Ymodem协议简介
2 P# L; ]+ I# ~9 F

  Xmodem、Ymodem和Zmodem协议是最常用的三种通信协议。Xmodem协议是最早的,传输128字节信息块。Ymodem是Xmodem的改进版协议,具有传输快速稳定的优点。它可以一次传输1024字节的信息块,同时还支持传输多个文件。以下协议内容的简介,顺便添加了一点自己的见解。


; i6 q, x8 W) \  d

2_meitu_2.jpg

+ q0 R; S- U: w) u# Q0 U
/ ?4 i8 e# b& F0 K. D0 ]" o9 H
  YModem,数据的发送回使用CRC校验,保证数据传输的正确性。它每传输一个信息块数据时,就会等待接收端回应ACK信号,接收到回应后,才会继续传输下一个信息块,保证数据已经全部接收。

# j7 d4 s- X- k$ p6 a/ K4 O4 `5 A

  1. SENDER:发送方。% {) Y" @) r' u& R; E  Z5 P/ ]
  2. RECEIVER:接收方。
    - R! r( Y2 T2 m+ X' V4 l& `( S
  3. 第一步先由接收方,发送一个字符'C'  u. M4 u$ b3 u
  4. 发送方收到'C'后,发送第一帧数据包,内容如下:* W1 k( f' L; b6 }, ^
  5. **SOH 00 FF  filename  filezise NUL  CRCH CRCL**7 q& L) i6 Z: _5 a- S% U
  6. 帧长=3字节数据首部+128字节数据+2字节CRC16校验码=133字节. a4 G! q  v% h
  7. 如下所示:
    + ]) U( k7 q, K- L6 f
  8.      SOH 00 FF Foo.c NUL[123] CRCH CRCL/ N# ^/ |3 _( j
  9.         第1字节SOH:表示本包数据区大小有128字节。如果头为STX表示本包数据区大小为1024字节。
    ! ^% V9 B& x# I8 t
  10.        
    : d0 M9 Q" R5 @7 M9 c5 _3 `
  11.         第2字节00: 编号,第一包为00,第二包为01,第三包为02依次累加。到FF后继续**从0循环递增**。这样就会出现一个BUG,那就是文件在传输大小上有限制,256x128 = 32768 字节 **32K的限制**。
    1 U1 k: w0 i; K% _" Y5 s' v
  12.         ( N  W0 I) |- p; o! ]/ ~9 g
  13.         第3字节FF: 编号的反码。 编号为00 对应FF,为01对应FE,以此类推。
    3 K! m0 Z1 g3 |% f. R( f
  14.        
    % Y. X& G2 @- ?# {  X( M. S: G
  15.         第4字节到最后两字节:若第1字节为SOH时有128字节,为STX时有1024字节,这部分为数据区。“Foo.c” 文件名, 超级终端下,在文件名后还有文件大小。官方dome也是因为使用了这个文件大小进行比对。这就是为什么用SecureCRT中的YMODEM协议而无法正确传输的原因。在文件名和文件大小之后,如果不满128字节,以0补满。最后两字节:这里需要注意,只有数据部分参与了效CRC验,不包括头和编码部分。( i& Z5 T# k1 X, K% Q" w
  16.        
    6 W  M" o  ]* |! t) E
  17.         CRCH和CRCL分别表示16位CRC校验码的高8位与低8位,高字节在前,低字节在后。- x% W1 P6 i5 F
  18.         6 K; R( K1 K# [6 S, Z% r$ e/ p
  19.         接收方收到第一帧数据包后,发送ACK正确应答。8 t! u2 C2 f/ }4 ^9 V) ]
  20.         % R$ B7 G& q0 S8 `- T0 x
  21.         然后再发送一个字符'C'。9 u' R9 }. m0 z& y7 L% r
  22.         " w, E! O* ]. o2 q
  23.         发送方收到'C'后,开始发送第二帧,第二帧中的数据存放的是第一包数据。
    " Z3 W5 H% z1 @8 P1 r- m% l! ^
  24.        
    3 U( \& N  |( r* P8 i  N" _. Q
  25.         接收方收到数据后,发送一个ACK然后等待下一包数据传送完毕,继续ACK应答。直到所有数据传输完毕。8 ], `8 q3 M% B5 L# T+ [2 |" p
  26.        
    9 k# g2 d2 @3 J2 B% X
  27.         数据传输完毕后,发送方发EOT,第一次接收方以NAK应答,进行二次确认。3 X" L' }! a. M% L( [9 G
  28.         ! t+ _5 ?5 x8 r
  29.         发送方收到NAK后,重发EOT,接收方第二次收到结束符,就以ACK应答。
    ( D0 q- c& s: _- @9 O
  30.         & c3 m/ o) @7 I: X2 L0 @
  31.         最后接收方再发送一个'C',发送方在没有第二个文件要传输的情况下,
    * i& b4 [- w+ j5 m$ J. o$ b8 g
  32.         发送如下数据:
    7 z: x, u  X- z, i* b  g" ?" y/ J6 ^, l
  33.                SOH 00 FF 00~00(共128个) CRCH CRCL ( g- h+ @( }6 C
  34.         接收方应答ACK后,正式结束数据传输。
复制代码

$ e9 p( G9 v8 z2、Boodload程序+ u; l2 w2 s1 k2 M/ g

下面所示的部分是移植的文件,移植完成后的工程文件截图:

) Z5 k1 D: Y/ v# k0 l

3_meitu_3.jpg

: O+ e2 a7 G- e
, O% B8 J) @% G, d4 C. n
main.c 文件修改添加:
) J7 D, M0 }, I4 i3 M* L
4_meitu_4.jpg

  J9 O( n3 N3 R" c) o' _
9 D8 P( R* m. B& f- N* }3 u6 Y


/ o( E4 F! M5 V" I
  1. /* USER CODE BEGIN Includes */
    0 S0 T7 O% X- D* ?2 p; X# i8 P" e
  2. #include "menu.h": B! w2 I6 y& L4 p' g9 `
  3. #include "flash_if.h": ]  R% I# G% \/ \8 E
  4. /* USER CODE END Includes */
复制代码
0 Q8 j; G+ o/ x) ?' h# h) D

) [8 N/ l& _  [* l" q0 B. k  i

5_meitu_5.jpg


8 K; ~; |+ x: u+ f, C/ n" v; `
  1. /* USER CODE BEGIN 0 */. D# O( h2 `) _" M% C4 E# o
  2. extern pFunction JumpToApplication;; O; k- H/ E6 {1 [
  3. extern uint32_t JumpAddress;
    ! r1 M8 {8 f; Q( ]9 q; t
  4. /* USER CODE END 0 */
复制代码
# A/ }& f1 l0 N8 c# p. n+ b  r3 q2 l

6_meitu_6.jpg


; v& f& e" n' U1 b0 D* Q! E! ^) s) i  u  E7 X+ f: \* P
9 t' x* x/ i" f1 w
  1. /* USER CODE BEGIN 2 */
    0 I$ u+ M* f0 v  S
  2.   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
    ! `7 V  A. J+ P
  3.   if (1), k  e- ^# q1 N
  4.     {3 B0 f1 n. C0 z* C7 `# B
  5.       /* Execute the IAP driver in order to reprogram the Flash */
    1 b5 A$ O4 |) D" v
  6.       FLASH_If_Init();) R8 V" n4 R$ ]5 D
  7.       /* Display main menu */
    5 I/ z- v. B7 N( t7 }( A/ B* R
  8.       Main_Menu();( @5 p. t0 p2 l, ?% g
  9.     }, }6 G/ V6 R" g+ i" h+ V2 \" G
  10.     /* Keep the user application running */. K2 ^  e) \. L+ i2 q
  11.     else
    ( Q# C" j3 C( N9 |1 p/ N
  12.     {# J% p/ Y7 |7 K4 i- R
  13.       /* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */) c8 k. s' p% X1 W
  14.       if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)  检查栈顶地址是否合法.
      O7 P) n. K6 Y+ ~; w; c- L9 b
  15.       {7 T3 ]6 d$ Z( q% C7 X& a5 W# q
  16.         /* Jump to user application */# D& F* G0 C0 d( b3 l! G9 }
  17.         JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); //用户代码区第二个字为程序开始地址(复位地址)
    $ a6 z" N8 {" V& B4 p; `  c- C
  18.         JumpToApplication = (pFunction) JumpAddress;9 k6 B! `( m/ g
  19.         /* Initialize user application's Stack Pointer */
    : _' f* n+ W0 U0 v" I* ?& Y
  20.         __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址); X4 n  c5 l- w& a% v
  21.         JumpToApplication();  //跳转到APP.' k+ U) J# }2 b: ~8 M
  22.       }/ l( b" S3 H1 o' D
  23.     }
复制代码
- m. U" v) t6 y: J

还要修改flash_if.h 头文件里面的地址。


- P* U- c& @! ^0 c4 r$ v

7_meitu_7.jpg
# F9 @0 r6 [2 N4 b- o* R  u
  H: y/ b- h) S4 V& b! q* v2 v
APPLICATION_ADDRESS 是偏移的地址,可以根据自己程序Boodload文件大小自己设置,USER_FLASH_SIZE 是 APP文件的大小。

1 o0 q# i) r0 |. U( Q


+ a2 B  q: e- _) l6 h4 v

2.1 传输32K限制解决
6 f8 E2 P/ K8 d% k2 V

  secureCRT每包只传输128个字节的有效数据,而每个帧的标号由一个字节表示,所以等到标号到达0xFF之后,下一个帧的标号又变为0,而官方Ymodem程序是判断帧标号为0则认为是传输文件的第一个帧,即文件名和文件大小。所以等到标号由0x00-0xff再到0x00的时候,它认为是一个新的文件,所以出错。只要加一个标志标明第一次出现的帧标号为0的帧为第一帧就OK了。
! I6 }+ w5 R% _, Hpackets_received 声明为U32类型的数据,判断的时候修改如下, M9 `$ S5 q) C/ H
if (aPacketData[PACKET_NUMBER_INDEX] != (packets_received & 0xff))


  }$ j3 L( O' G; k' b
$ r, a' z) K1 ^  L6 }  p! ]. E
8_meitu_8.jpg

. d' w) L/ t" n% a# K9 x4 t7 H' Y) A1 H0 P4 s8 J

111.png

& J  c- f; E7 X# W
3、APP程序
0 n5 m% g/ K" e( Q: @$ }

App需要修改内容:


4 K0 x  v5 N" s( Q# C9 x编译链接其实地址


; Q# F2 P' F5 D4 R5 a8 k9 W

9_meitu_9.jpg

3 X+ K( f- j8 ?" @: e
中断向量修改。6 q6 C# U% ?3 e+ @0 e7 E
10_meitu_10.jpg

! L, T2 S- w2 {9 `$ r
9 V" W$ r/ o/ Z* Z

4、升级测试
- d4 X* T- V# i* m0 e4 w

软件使用secureCRT发送文件。
, g" I! y5 x' B2 G; K* @

11_meitu_11.jpg
) d' `$ P# o5 ^9 o% j
8 n) ?9 o; Y. ]4 L( {* ]$ _
12_meitu_12.jpg
* c) L/ u$ b& q1 L$ g1 j6 S

6 L* \3 c% J( D# k/ R" \. d' m/ x2 T* M! _: v) v, o6 ~2 b: {
13_meitu_13.jpg

# @4 r6 G7 _1 z$ S4 t7 i2 o* T
3 |% Z5 O/ B# t! D: t
- p; E- k8 y! o; x+ ]' [


0 Q# @* A) e* ~/ l' @) \, i* ^* B0 }$ k' R0 h
收藏 1 评论4 发布时间:2020-9-21 10:16

举报

4个回答
wyxy163@126.com 回答时间:2020-9-23 09:01:59
提示: 作者被禁止或删除 内容自动屏蔽
常春藤 回答时间:2023-9-23 09:17:41

官方版本库太旧,移植时候出现大量写保护的相关的寄存器找不到定义

rasingsun 回答时间:2024-2-1 17:59:32

这教程对F0系列App部分有点不适用

我调通了

稍后发个教程

赞宇 回答时间:2024-4-7 10:50:23

不考虑接收方接收异常的情况么

所属标签

相似分享

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