基于RT-Thread nano的通用Bootloader框架(兼容官方打包加密软件)

发表在 Bootloader2019-12-2 22:25 [复制链接] 40 1156

基于STM32的开源Bootloader框架-RT-FOTA

# K3 K  K2 R3 N5 X

简介

; n7 H4 \" x8 x, E) B* D% Q. ~/ I

RT-Thread官方推出了STM32系列单片机的通用bootloader,在其网站可以通过网页配置就可以生成bootloader的烧录文件,使广大嵌入式工程师不用编写一行代码,就能够轻松完成自己产品的bootloader功能。但是由于RTT官方的bootloader软件RT-OTA是商用性质,不公开源码,不仅仅限制了在其他平台的移植,而且也不方便加入产品的特定功能。本人软件水平有限,但是基于对开源精神的崇拜和RTT多年的感情,蒙发出利用业余时间编写一款开源的且基于RTT系统bootloader通用软件,贡献给大家。

& @2 {+ z8 R$ N2 p; M; T

由于RTT官方推出的bootloader名字叫RT-OTA,因此为了蹭点RTT的流量,我这个bootloader名字就叫RT-FOTA。

1 I, T: f" R6 ?1 ?, j' w

【RT-FOTA的需求分析】

! V/ o* c. J, C  e  d
    , t! l4 K3 L7 S6 \8 C& h
  • ( c( E' S* p, `! i3 M( i0 W. T: H' M

    开发基于ROTS的bootloader软件,网上很多牛人会说bootloader最好是裸机程序编写,就像u-boot一样稳定和可靠。但我个人认为目前32位单片机资源丰富,RT-Thread的稳定和可靠性不言而喻,加之RTT的组件丰富,后续功能拓展方便(比如加入网络和USB功能)。因此我使用RT-Thread的阉割版本rtt-nano实现。

    & O8 ?1 Y9 _' G! u( B, I! ^8 k
  • : U# r+ p8 Z; H, |; E; H) S
  • 0 i! Q, q' Z% {: C1 |7 z( [1 J

    兼容RTT官方的rbl文件:使用RTT官方的打包软件生成下载文件,可以实现加密压缩功能。由于个人水平问题,只能做到尽可能的兼容,比如RBL文件里面的HASH_CODE我就不知道怎么计算出来的。

    & m$ v5 {. U4 D, J  H4 j
  • ; G6 Q8 F" v6 P( D  ~; m" u2 k
  • 移植方便:由于RT-FOTA基于RT-Thread开发,因此只要你的平台被RT-Thread支持,就可以很方便的移植到。
  • ) F5 w+ u+ ^* X1 l# p
& d0 l/ Z. u. h+ r

【RT-FOTA主要的功能】

: g. G, I' `9 a; N1 N. m
    - X' D3 G) }: m/ U. S
  • 支持RTT官方的RBL打包软件,使用方式也一致。目前支持包括CRC32、AES256、quicklz和fastlz功能;
  • 5 c' J, \8 s  M$ B5 l  @) _
  • 支持命令行模式(FINSH组件)和出厂固件恢复;
  • 1 |1 P" e4 E  \" k+ @0 Q" u
  • 支持FLASH分区(FAL组件);
  • 0 {2 N7 S$ P  z/ M8 @
  • 支持功能扩展(RTT组件);
  • ' H2 b& M/ `; H) _) x0 y$ F! }
  • 其他功能可自行方便扩展;
  • - @; W  g& r( o, w4 ?) @
* e* j( _9 d5 l6 z7 J

软件开发目录

! O+ G1 {  t& D- L- X' k& g- e

软件开发目录参照RTT的目录形式,如下图所示:

! T% ^& z# P& w1 R( o& S( G2 q

目录

% Y4 t2 |5 ~* L/ W3 M5 E

我原本计划添加SCONS进行编译,但目前对SCONS的使用还不熟悉,下次再实现,因此暂时使用MDK 完成。

: t% x# K) S- @( r/ h

可以看到我并未按照RTT官方推荐的使用MDK或cube生成rtt-nano的工程,原因是我有强迫症,感觉IDE生成的目录很不爽。

& M" U! Q5 n$ \+ z7 P3 K

软件配置说明

* D. W) X  B, x3 `: ]

RT-FOTA的软件配置仍然集中在rtconfig.h中,其中一些.c文件中有一些默认的配置宏,但可以根据需求进行修改。

0 v" L" n: S/ b7 o, u
/* RT-Thread config file */! C  G1 `7 S) a+ _
#ifndef RT_CONFIG_H__- x2 t+ `6 [: \! v! E+ t/ @" C
#define RT_CONFIG_H__
) V1 ]. o) B( [* D6 b: h
, x! |6 Q; o4 \+ `3 H5 C3 g#define RT_THREAD_PRIORITY_MAX      80 e2 a2 \/ }, R8 F+ m2 x6 z- R
#define RT_TICK_PER_SECOND          1000' M  h6 S; q' k8 ^$ N0 A
#define RT_ALIGN_SIZE               4
' _2 H& @" P/ a4 I#define RT_NAME_MAX                 8
- L7 D- T3 h2 |, |5 r: x% z. t
. e( @* B1 I: E2 Y2 N$ f/* Kernel Device Object */  
0 |# L9 h8 k- t7 L, k#define RT_USING_DEVICE
# s0 g, `1 V: z; J#define RT_USING_CONSOLE! L5 y1 I9 k; \9 J4 i; ]
#define RT_CONSOLEBUF_SIZE          5129 L0 m+ R7 ?* ], ?3 B1 e0 p% D
#define RT_CONSOLE_DEVICE_NAME      "uart1"
4 P6 {# X- k: ~$ ~9 H' J" ~  T#define RT_VER_NUM                  0x301026 R/ S' Y9 G6 A0 u4 O5 K

2 D; N, o6 }0 o! I1 ^1 h) R8 i: I#define RT_USING_CPU_FFS* b! m$ G  m" S2 {; m5 g- v2 S- _. c5 ?

$ r( C/ v5 Z1 b( b9 e1 \/* RT-Thread Components */4 Z3 t- T) u, F6 O* o3 E
#define RT_USING_COMPONENTS_INIT
0 ?8 n4 [) O$ n#define RT_USING_USER_MAIN% D: z/ t$ l' N+ z2 D# ?* M
* a- s1 T& t4 |: M4 b7 h! B! y
#define RT_DEBUG_INIT 0* d3 `4 z0 k" J7 o! w! r
#define RT_USING_OVERFLOW_CHECK
  i) |8 f8 I3 A( _2 \4 V// #define RT_USING_HOOK6 b4 Z& N9 L2 e2 v" w5 c* H' E% ~
// #define RT_USING_IDLE_HOOK. i7 Z1 J( F. q6 A8 U

! ~6 W% K8 n; z# f" @! S# ?/* Software timers Configuration */ " y) @9 F9 c& r9 Z3 Z, k0 V
#define RT_USING_TIMER_SOFT         0
" n9 Z$ P/ \- h2 n; b$ N2 c& p% t, q; `#if RT_USING_TIMER_SOFT == 02 B( C- O4 K; ?$ k4 W
#undef RT_USING_TIMER_SOFT
+ |( P' i0 o7 K) P#endif
0 M# ]" M9 ~, u# O/ Q8 N
9 E; o' d( s" O/ W/ `  x" k3 l#define RT_TIMER_THREAD_PRIO        4
7 t4 h: U' d5 r5 @5 q#define RT_TIMER_THREAD_STACK_SIZE  512
9 V4 m7 Y0 ]3 ^. Y#define RT_TIMER_TICK_PER_SECOND    100* G! q' ^& B; y8 }; W8 E0 S
/ v8 {, w% F& s' V
/* IPC(Inter-process communication) Configuration */
0 `- J7 j8 K/ `2 W, f#define RT_USING_SEMAPHORE: p5 c6 }% g  r. V2 ?
#define RT_USING_MUTEX
, @3 g% i. n( q5 U$ D$ z//#define RT_USING_EVENT
( C" \8 l! @# ^9 G5 I1 q' }# s//#define RT_USING_MAILBOX- f# T& O5 V7 C% u0 i
//#define RT_USING_MESSAGEQUEUE, J1 S" X/ B! e1 L, }3 G# r3 q/ k5 I
1 S2 o4 N1 m" u2 ]' B$ c
/* Memory Management Configuration */9 D7 U1 T5 q' P/ q( y0 @/ B
#define RT_USING_HEAP
+ l8 j' v! x% f5 i, m#define RT_USING_MEMHEAP' }8 S/ Y; }$ E- h  K0 f7 v' c
#define RT_USING_SMALL_MEM% ?. r0 |9 t  L

. w0 P1 A) `. g# R/* Finsh Configuration */1 [; k* J4 r! s# i; o
#define RT_USING_FINSH
( x' ^% S; E$ U9 l( Q7 r#define FINSH_USING_MSH
! j7 q0 @# b& ]$ Y+ P+ z$ }# m#define FINSH_USING_MSH_ONLY0 a) A1 ~- r0 b! p" d4 i& v
#define __FINSH_THREAD_PRIORITY     5% X5 ^% f+ |& \$ o& J
#define FINSH_THREAD_PRIORITY       (RT_THREAD_PRIORITY_MAX / 8 * __FINSH_THREAD_PRIORITY + 1)
+ d/ g+ C3 G4 u8 p; |6 b+ B#define FINSH_THREAD_STACK_SIZE     2048" f; n4 L" @/ ~- G
#define FINSH_USING_HISTORY$ K0 A2 Y3 @# |% ]" G" I* Y7 e
#define FINSH_HISTORY_LINES         5: I; m' a& Z8 G; W, X) ~
#define FINSH_USING_SYMTAB
  k3 O; ]/ v5 l6 Q: S! ^#define FINSH_USING_AUTH            /* 可配置FINSH的authencation功能,防止随意使用FINSH */. W" w" n  o+ X7 W
#define FINSH_DEFAULT_PASSWORD      "radiation" ' t7 c9 d, t  F) L+ I( t
#define FINSH_PASSWORD_MIN          6
/ ?( T0 ^6 Y& [#define FINSH_PASSWORD_MAX          16  9 O" o# ]1 Q( I& r$ l+ k/ ~" Q+ {

1 l- A- I0 w  v6 [/ D& g* o$ w/* Device Drivers */    # Z) _6 J: u* Q5 [& h* Z" D4 o
#define RT_USING_PIN
: C1 p0 v) U: @#define RT_USING_SERIAL
0 x, N5 z! V6 m( \4 n( t$ o// #define RT_SERIAL_USING_DMA! z& u( U1 ]3 n
#define RT_USING_RTC8 {. q  o/ |( Q- L
#define RT_USING_SPI* `: l( G2 h( `6 t
#define RT_USING_SFUD
$ H) t/ x3 v7 v#define RT_SFUD_USING_SFDP
& c/ @! }2 I7 s) {+ {, K#define RT_SFUD_USING_FLASH_INFO_TABLE; T  h" W% i0 I& Y: G* U
#define RT_USING_WDT
2 f/ ^7 J. J6 H5 l
" Y# h$ C) ?2 C/* RTT组件配置 */: n! y; U3 w. D; v
/* fal package */  R8 K+ p: V1 [6 O) V% W
#define PKG_USING_FAL" ?% j3 T% r3 a/ ~' c3 H, {
#define FAL_DEBUG_CONFIG
; n$ T7 A& A8 p: f5 [/ p: E4 \6 I#define FAL_DEBUG 0' d3 v1 d- f: l2 V2 G4 i
#define FAL_PART_HAS_TABLE_CFG
7 _2 R6 |/ f6 y#define FAL_USING_SFUD_PORT$ I9 U3 {! ?" t& E
#define FAL_USING_NOR_FLASH_DEV_NAME    "nor_flash0"- |; c8 p7 o/ V& h/ g8 S. _5 r
#define PKG_USING_FAL_LATEST_VERSION
9 W7 {5 u& Z* N: E) z# \& t#define PKG_FAL_VER_NUM                 0x99999
- }" y8 S5 u  m& S+ I' K7 C9 g
% z  Z; f( x$ I0 V/* Tinycrypt package */$ [) m4 b  E# u
#define TINY_CRYPT_AES* c8 O( }6 t, E5 y; ~  d* p$ R
1 ]9 z$ N, A! e$ h" c- j6 m# I
/* Compress package */
$ E* x3 C, T8 F1 y6 e' N#define QLZ_COMPRESSION_LEVEL   3) N% j- G4 z3 S7 h; g+ ?9 g0 U. t

; B( _4 H8 p! k4 T( z2 u/* Hardware Drivers Config */
8 L. N+ E# c% [8 o2 F3 r; Z3 q#define SOC_FAMILY_STM32
2 e" R+ b- x4 R9 X2 [& R#define SOC_SERIES_STM32F41 S: R4 ?1 t9 B. ?7 K7 |
#define SOC_STM32F407ZE9 |$ f; p+ V+ N4 w( y) W

3 r$ i3 r+ b! B; K/* On-chip Peripheral Drivers */    * @( f" j* V1 h. ~' g
#define BSP_USING_GPIO
8 {6 d/ V' v! M! d/ b1 C2 N- w& R( Z#define BSP_USING_ON_CHIP_FLASH
8 _% ]4 }5 {. j/ t#define BSP_USING_ONCHIP_RTC
3 |. R5 [' i/ T. k9 D#define BSP_USING_UART4 Y1 P& h, a, Y' L
#define BSP_USING_UART17 x- ?2 x6 J4 P- v% [
#define BSP_USING_SPI/ @( X; e0 G0 g
#define BSP_USING_SPI1, W" o6 l- a) j/ @3 u% G% t5 ~( q( }6 R

1 f/ Q( G! L! G, z* N7 L5 T9 n/* Onboard Peripheral Drivers */    / ?& l* c7 Z* x
#define BSP_DATAFALSH_CS_PIN 30
3 O/ a# y- H; b
+ s4 H2 J/ B! M/ V+ o  P/* Board extended module Drivers */ " o! e' @4 Z- U6 G0 w9 H- p% P
#define BSP_RS485_DIR_PIN 52
. J8 i! ?# A- g7 j$ U7 {, W0 f2 v  n* w, w' _
/* RT-FOTA module define */  @' n' U' P. S) L2 Q8 s
#define RT_FOTA_SW_VERSION      "1.0.0"
, a' \. [2 Q9 b8 u, m, y
0 D7 h; `9 O+ _# C7 k9 W/* Enable Ymodem OTA */* {+ R4 M9 ^* o5 {) W; g
#define PKG_USING_YMODEM_OTA) _- F. `& R8 \: _6 [
( v6 x7 V. t( }, _1 E  \/ N2 a
/* 分区名字可以根据自己的需求而定 */
7 p/ w- Z* p) [* k- a# M/ {7 Y/* FOTA application partition name */
: ]9 u3 X0 B- f' ~#ifndef RT_FOTA_APP_PART_NAME- e* _' `4 s7 `6 c+ c
#define RT_FOTA_APP_PART_NAME   "app"  _2 h" m9 e" Y* e0 G
#endif  
* t) y/ A  o! v" X( z* X- l! y/* FOTA download partition name */& A8 j& a7 {* o- k: g! F, u/ o! p& R
#ifndef RT_FOTA_FM_PART_NAME% w- ^$ e" B$ U3 a; L# R
#define RT_FOTA_FM_PART_NAME    "fm_area"0 L% m0 m) j  }
#endif  
" {! S  |+ ?; O. i1 j/* FOTA default partition name */6 s4 B4 S4 O/ J0 B& O
#ifndef RT_FOTA_DF_PART_NAME
* m+ k0 v! v+ G#define RT_FOTA_DF_PART_NAME    "df_area"7 d- |% l  c; B& p
#endif
# n3 D; `8 }! D' U2 @6 M1 |0 t: @3 I- A. n  Z5 O
/* 此两项密码必须与RTT的打包软件设置一致 */
  i' w# \* O$ o, d/ K4 C" D" U% N/* AES256 encryption algorithm option */# s1 q1 L0 U5 o4 t
#define RT_FOTA_ALGO_AES_IV     "0123456789ABCDEF"* X1 H8 Q5 i& \
#define RT_FOTA_ALGO_AES_KEY    "0123456789ABCDEF0123456789ABCDEF"  
8 `) z$ g  Z' w2 l#endif
/ W2 p9 U$ @7 G, g9 A( R, o& `

RBL文件说明

4 r, |* [* ^7 _" ^5 N* c( w

使用过RTT官方的RT-OTA组件的朋友都知道,下载的不是bin文件,而是需要通过RTT打包软件“装饰”成rbl文件之后,才能被RT-OTA识别。

0 P2 ~! P, d; W. J- S/ S

RT-OTA打包软件

' {* U5 E6 D5 d8 n5 _* w! n

RTT的打包软件可以设置代码加密和压缩,其配置信息都存在rbl文件前96字节中:

5 l  L  W5 y1 h  t
rt-fota />fota show fm_area 0 96
7 [4 k! `# v* \2 b$ X+ B00000000: 52 42 4C 00 00 02 00 00 5E A9 A4 5D 61 70 70 00 
/ t+ I3 T6 Q4 Z( w, d00000010: 00 00 00 00 00 00 00 00 00 00 00 00 31 2E 30 2E % U& i$ V9 j0 d$ u# d
00000020: 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * L. g+ [/ P% s' U
00000030: 00 00 00 00 31 2E 30 2E 36 00 00 00 00 00 00 00 + c1 s5 g9 M  `* j2 E' U
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 43 33 29 0A : a9 K3 p/ f3 V
00000050: 47 08 F6 DA 84 BB 00 00 1C 84 00 00 C4 3D E3 B5
0 R1 D: f8 z$ q) g: Y0 _

其具体含义如下:

. s' X* D9 P9 \. I
typedef struct {  y% T2 f3 m& X+ N" _1 X
    char type[4];               /* RBL字符头 */ $ R1 D1 y% ~8 x/ v$ S6 ]' W+ L8 \
    rt_uint16_t fota_algo;      /* 算法配置: 表示是否加密或者使用了压缩算法 */
) g: A  T6 M; j0 l+ D    rt_uint8_t fm_time[6];      /* 原始bin文件的时间戳, 6位时间戳, 使用了4字节, 包含年月日信息 */7 i  a9 Y- b- b: m- X( ?2 X/ F
    char app_part_name[16];     /* app执行分区名 */
8 t2 k; n% K8 t- Q; N3 i5 d4 Z& P    char download_version[24];  /* 固件代码版本号 */' P% ?, G5 C. h5 e( G* g. V
    char current_version[24];   /* 这个域在rbl文件生成时都是一样的,我用于表示app分区当前运行固件的版本号,判断是否固件需要升级 */
/ C' [5 p, c2 W) {    rt_uint32_t code_crc;       /* 代码的CRC32校验值,它是的打包后的校验值,即rbl文件96字节后的数据 *// N; s& ?: D$ R" N" ^7 y0 [
    rt_uint32_t hash_val;       /* 估计这个域是指的原始代码本身的校验值,但不知道算法,无法确认,故在程序中未使用 */
+ @4 A+ n) ]! W$ w' q    rt_uint32_t raw_size;       /* 原始代码的大小 */
& q2 c& X% I- O) S4 ]5 P- J8 I! U" \    rt_uint32_t com_size;       /* 打包代码的大小 */, ~' d, h: q6 Z1 {
    rt_uint32_t head_crc;       /* rbl文件头的CRC32校验值,即rbl文件的前96字节 *// b3 `# i& S1 \7 b3 x
} rt_fota_part_head, *rt_fota_part_head_t;
- l/ _1 P8 T# u+ Z% E3 M* Z

开机界面

% g+ }1 j& x4 c/ S  n! r

RT-FOTA开机界面如下图:

  B) h: Z7 w, v  r1 Z9 y/ k

开机界面

3 b/ X  v8 q3 }2 w& X1 j+ r

可以看出使用了RTT的SFUD和FAL组件,同时列出了分区变信息。

) _* h# L( B5 o1 x, r  Y) X+ @

RT-FOTA源码公开,你想怎么改就怎么改,不在受限制:)

" N5 K, x- N) l

最后一行是表示在5秒钟内,按下Enter键,即0x0d,就可以进入命令行模式:

. k% v0 u; N0 S- }4 X& R* e

命令行模式

2 h' _8 N6 `% \* \0 K5 v3 g

由于FINSH具备authencation功能,可以设置shell密码。具体详见RTT相关文档。

* A4 P0 ?( x) [' S$ X

命令行模式

' H0 q# d& n/ ^' l( I1 v

RT-FOTA的命令行模式使用的RTT的FINSH组件, 除了RTT系统自带命令外,还增加fota和ymdown命令:

- \, I9 c9 L1 O) @/ a5 @% M

fota命令

' B4 U: W0 q$ D& o3 A/ W# F* W

键入fota命令后回车即可看到帮助命令:

' t( K6 x+ y" U8 l3 ~
rt-fota />fota1 D$ b- h1 m# m+ t5 F. b) U/ q6 z4 m' @) x
Usage:
) d- M  v0 d2 h  b$ |  ufota probe                       - probe RBL file of partiton. V. W2 Q( Q$ A2 S
fota show partition addr size    - show 'size' bytes starting at 'addr'4 M0 G3 J6 ]) N1 y$ R8 x- N
fota clone des_part src_part     - clone src partition to des partiton
" G/ G& ~  N+ {6 a" w' c; v% Mfota exec                        - execute application program
3 o! \6 y( b! I: i+ n

probe参数可以打印出当分区的RBL信息:

* a: R/ e6 f' _
rt-fota />fota probe
+ i9 T5 m+ [1 V- Y/ Z[I/fota] ===== RBL of fm_area partition =====
/ R5 r8 e: S# a% `. y. ?( k[I/fota] | App partition name |         app |
$ E5 w9 ~( _: [, z6 k+ X[I/fota] | Algorithm mode     |  AES && QLZ |3 S0 m6 G& e; k1 e& P5 H
[I/fota] | Firmware version   |       1.0.3 |
1 I3 n/ }" |6 ~% g" |; G& d4 \[I/fota] | Code raw size      |       48004 |
; y: C; \4 a. N' x4 H8 w& s[I/fota] | Code package size  |       33824 |
$ q( l8 j. i6 v# F[I/fota] | Build Timestamp    |  1571072350 |
0 q' J+ `: A+ c" ~[I/fota] ===== RBL of df_area partition =====1 u2 a+ o' g" m( L5 e8 S! J9 w
[I/fota] | App partition name |         app |
0 i$ `5 A; p. p& f# @[I/fota] | Algorithm mode     |  AES && QLZ |4 i8 Q% V1 B  W5 E
[I/fota] | Firmware version   |       1.0.3 |
+ B3 t# J- X1 J, |[I/fota] | Code raw size      |       48004 |
" d0 j' _- @  i- A6 `0 P4 G7 K7 f[I/fota] | Code package size  |       33824 |
( @7 n0 j+ Z8 c$ f. `+ I6 q. D+ b2 m[I/fota] | Build Timestamp    |  1571072350 |
/ T; K; f; I( K

这里列出了fm_area和df_area分区中RBL文件的主要信息项,便于开发者查询:

% n+ W; \: f% |; c' v

App partition name: 指的是RTT打包文件时设置的分区名

& Y7 P/ u4 P: W8 @

Algorithm mode    : 指的是RTT打包文件使用那些算法:AES256/Quicklz/Fastlz

6 ?2 U- H4 ]2 D5 i/ q) f

Firmware version  : 指的是RTT打包文件设置的固件版本号

3 }, z# a7 B7 O- O8 z* u3 A

Code raw size     : 指的代码原始大小

0 Z  ?% |9 W1 E  Y9 H2 ?6 H! g! a

Code package size : 指的代码打包后的大小

9 p4 \  r$ n) W

Build Timestamp   : 指的代码生成的时间戳

/ d; v! L+ n- K: P

show参数可以显示分区的具体实际数据,方便调试与检查:

6 @* C, ~9 }3 W- q1 r6 |
rt-fota />fota show app 0 96
! q. {5 \) }+ G# k: q00000000: C0 08 00 20 E5 57 02 08 5D 04 02 08 5F 04 02 08 
: \5 ]4 U" z. V6 g: `00000010: 63 04 02 08 67 04 02 08 6B 04 02 08 00 00 00 00 
! ~% ?  l" k: S6 l8 S0 J% ^00000020: 00 00 00 00 00 00 00 00 00 00 00 00 6F 04 02 08 ! C! y/ i& D( ]5 N! _% U& ]
00000030: 71 04 02 08 00 00 00 00 73 04 02 08 75 04 02 08 + z# D# d& |0 ^: U: R2 }# I3 I
00000040: FF 57 02 08 FF 57 02 08 FF 57 02 08 49 55 02 08 2 S( n+ R2 L; n: r
00000050: FF 57 02 08 FF 57 02 08 FF 57 02 08 FF 57 02 08 
! M0 X) W6 L+ L% q; c) @4 G

这里列出了app分区0到96字节的数据

* J- |& g! k# r8 i: \

clone参数是实现分区数据克隆

% ?  Y- j' w0 z# @: a
rt-fota />fota clone fm_area df_area5 a* u7 M1 D! h, |
Clone df_area partition to fm_area partition:# `. Y2 K& ]" z8 b
#########################################################
5 Q6 R6 A8 [8 ^9 m0 L5 E8 O#########################################################
' f* u: n% [7 m0 M" A#########################################################
$ h1 x7 v% i# h3 i' v#########################################################. w9 R$ @& i( Y8 n  R
############################
) i6 d7 ~4 I9 F% \& \( r; p$ |Clone partition success, total 1048576 bytes!
# I0 d# K1 `, ~+ G' X2 n

这里是将df area分区数据完整的克隆岛fm area中。

7 u# U% {& Q( p! |2 s

exec参数是用于执行app分区的应用代码

7 X. U, c& y6 D$ r0 s3 f; ^- e9 D
rt-fota />fota exec
9 Y, {) O. j; Y) M8 J0 I( R. }1 \[I/fota] Implement application now./ @+ z9 }$ L2 [5 l0 ]
 LCD ID:5510
/ B/ w1 D' U$ k

ymdown命令

% q; h; A4 L/ E

ymdown是基于Ymodem协议的下载命令,使用RTT的ymodem和ymodem ota组件实现,其中将ymodem ota.c中的DEFAULT_DOWNLOAD_PART设置为需要默认使用分区名,即在使用ymdown不带参数的情况下就下载到DEFAULT_DOWNLOAD_PART分区,也可加分区名作为参数指定下载位置。

% n( ?, ^8 D9 v1 T2 Y# o  I3 }
rt-fota />ymdown
8 y2 ~& d8 {; n& |0 O4 _Default save firmware on download partition.( [1 t0 l, T8 `( O
Warning: Ymodem has started! This operator will not recovery.2 M6 z  w, J( F
Please select the ota firmware file and use Ymodem to send.3 y, Y. i2 L# f5 E
CCCCCC
( ?; p; ~7 S/ Q* Z* p% BStarting ymodem transfer.  Press Ctrl+C to cancel.
; B# s) @% g( B5 `6 n4 o9 p  100%      33 KB    6 KB/s 00:00:05       0 Errors
# T' X8 l3 ]" D
: f  p1 s4 J  e$ I& M  c! P8 uDownload firmware to flash success.# t+ h" y5 U3 K4 Q0 H! Z* M. u3 [
Download firmware verify........[OK]# Z3 H! z4 E, v: K& l4 B! B& t
Reset system and apply new firmware.
, c0 N$ m% |8 o! {4 Y- `( D

下载完成后,会自动复位重新启动,将新固件搬运到app分区中:

' E4 u" Y& T; G, t0 ]
 ____ _____      _____ ___  _____  _        
0 u8 F2 s1 Z4 k4 M4 Q+ m2 l" S|  _ \_   _|    |  ___/ _ \ _   _|/ \      
& a/ n! T! e' Z| |_) || |_____ | |_  || ||  | | / _ \      * p% r4 J' {) {% r
|  _ < | |_____ |  _| ||_||  | |/ ___ \     
1 @+ t4 @4 p) b. g& ?4 u|_| \_\|_|      |_|   \___/  |_/_/   \_\  
3 z3 Z, G3 E7 L, H$ {9 H2016 - 2019 Copyright by Radiation @ warfalcon 
* D: g, l4 W4 MVersion: 1.0.0 build Oct 18 2019
9 D3 }% Q+ u3 V& b% q# N" s5 K% w
[SFUD] Find a Winbond flash chip. Size is 16777216 bytes.
, {0 t9 u) w& ]; n/ B3 {$ `[SFUD] nor_flash0 flash device is initialize success.' u; y0 D9 @) S! S, Y
[I/FAL] ==================== FAL partition table ====================
3 K0 A/ S- x0 t7 E" {# u[I/FAL] | name    | flash_dev    |   offset   |    length  |" \1 H% l1 B, \/ ~- C
[I/FAL] -------------------------------------------------------------7 \7 W' n- ?' t3 O2 u, F
[I/FAL] | app     | onchip_flash | 0x00020000 | 0x000e0000 |
; V5 R, {% g1 w+ D; j8 q[I/FAL] | fm_area | nor_flash0   | 0x00000000 | 0x00100000 |
6 Q8 e* B! [0 \1 _2 I- `" _- u0 x[I/FAL] | df_area | nor_flash0   | 0x00100000 | 0x00100000 |
: u4 i( ~1 k: f" N[I/FAL] =============================================================5 _/ w2 x9 C& d. e; z* M% U
[I/FAL] RT-Thread Flash Abstraction Layer (V0.4.0) initialize success./ O; V6 U  o$ M+ s0 i
Please press [Enter] key into shell mode in 5 secs:
4 ?; T6 j& L$ P[I/fota] Partition[app] erase start:+ G& R% Z! N  }& v8 j0 I( g* I: P
[I/fota] Start to copy firmware from fm_area to app partition:; |  z! n6 \3 h
############. w. a- g; `) b4 W7 a
[I/fota] Upgrade success, total 48004 bytes.
. [" k1 z0 J# `, j2 A[I/fota] Copy firmware version Success!0 E8 L7 L5 t' t9 f, n( {+ t) r  }
[I/fota] Implement application now.0 x+ t6 ~0 f- _# Y7 d7 }& t' m$ b4 w
 LCD ID:5510
6 A5 r( O5 f. t

出厂固件恢复

+ E7 U7 V& ~( z3 m8 ^" f. Z; I

恢复出厂固件的方式比较多,本人多年的工程实践经验,倾向于使用外部按键长按后进行出厂固件恢复。出厂固件存储在df area分区中(分区名在代码中任意设置),长按按键10s后(长按时间在代码中任意设置),RT-FOTA会自动解密解压df area分区代码,并搬运到app分区进行执行。

2 {2 @: \# E" p* V. q
Default firmware key pressed:
( c* F9 ]& [3 I+ j8 j5 K) U>>>>>>>>>>
% U" p1 n* U! z5 J) Z[I/fota] Partition[app] erase start:
; N8 y2 a- b# V' N$ t  x1 N8 o2 i[I/fota] Start to copy firmware from df_area to app partition:
& n) G/ o; G/ h############4 E, O* _, z0 [
[I/fota] Upgrade success, total 48004 bytes.( p- i2 P, r  @+ c' A4 _. W& u
[I/fota] Implement application now.
7 b" _& h8 o2 {. K5 j LCD ID:5510
0 S4 t7 p% S7 e% s) p

RT-FOTA移植

) a; c3 d* T! ~( J! l: {

RT-FOTA移植很简单,只要RT-Thread源码包中有你的平台的BSP包即可:)

+ Y2 K; z; H5 s8 g8 S" d9 n

RT-FOTA中使用的各种组件的修改也很简单,比如FAL和SFUD就可以参照RTT官方说明,SignalLED参照源码包里的README.md即可。

' v3 j" W7 m( e, Q

RT-FOTA可以直接使用在RT-Thread的完整版搭载,只需要将rt _ fota.crt _ fota.hrt _ fota_crc.c放入工程中即可实现,然后用env配置相关组件即可。

! v2 \4 F$ a2 `0 y+ H, S/ R

编译下载

/ {1 p0 s- M; B$ f" a1 g

双击 bootloader.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。

- E0 X; ~7 o) g1 [
; J5 \/ n7 e3 E3 a  E! s4 w

工程默认配置使用 JLINK 仿真器下载程序,点击下载按钮即可下载程序到开发板

  F- x1 d8 U8 U/ v+ M* X( h4 y
) X1 ]6 {3 A% H4 i/ {7 F

运行结果

& c- k7 F- f! `1 k2 k9 ~

下载程序成功之后,系统RT-FOTA会运行:

# t9 J4 E; w6 S! m; ^
    ; T, Y) o% l$ j# T- T
  • 启动后LED会常亮;
  • . \# A4 M& p6 r$ |! W* B/ \6 C# j
  • 如果进入shell模式, LED会1Hz闪烁;
  • + y, w) c9 T; u* m
  • 如果进入upgrade模式, LED会10Hz闪烁;
  • / i* {! ]  w# x0 K1 E% H
1 ]0 b$ r1 q3 R' ~& K% Y

连接目标板的串口1到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-FOTA 的输出信息:

2 u7 V3 l, d7 @
 ____ _____      _____ ___  _____  _        
/ C8 W! h! D* j2 J( S|  _ \_   _|    |  ___/ _ \ _   _|/ \      
, Z2 L, v" l# o# B, e/ X+ A  e8 k| |_) || |_____ | |_  || ||  | | / _ \      - n0 G/ g$ U+ v( s
|  _ < | |_____ |  _| ||_||  | |/ ___ \     
7 S  s* \3 c% e  j8 u9 W|_| \_\|_|      |_|   \___/  |_/_/   \_\  1 E" p! y0 k' B3 d' I9 p# [7 w
2016 - 2019 Copyright by Radiation @ warfalcon 8 w1 A1 e7 W( H5 n) P
Version: 1.0.0 build Oct 18 20198 q. t+ h; k3 E6 g0 o7 z! |

+ z! w5 l2 o! _[SFUD] Find a Winbond flash chip. Size is 16777216 bytes.
5 l* U+ }: q8 e$ I[SFUD] nor_flash0 flash device is initialize success.- A9 H1 O2 n; h
[I/FAL] ==================== FAL partition table ====================- F( Y6 C- a- q7 `3 C: O4 a" N
[I/FAL] | name    | flash_dev    |   offset   |    length  |
5 j( R6 a- f% \, \2 c% x[I/FAL] -------------------------------------------------------------7 K  v4 m* o2 O, c
[I/FAL] | app     | onchip_flash | 0x00020000 | 0x000e0000 |  j& `; N8 \! l1 p# G/ f; b$ ]
[I/FAL] | fm_area | nor_flash0   | 0x00000000 | 0x00100000 |
5 G2 E: c. v2 c$ y2 s  ~[I/FAL] | df_area | nor_flash0   | 0x00100000 | 0x00100000 |
- c3 ^6 m; P6 ?+ h[I/FAL] =============================================================
+ ], I$ ?, n( E- o" [* y( K2 P[I/FAL] RT-Thread Flash Abstraction Layer (V0.4.0) initialize success.
" {; |& x. X* O( R' ~! e( x8 d

注意事项

1 F8 \) [! a0 p0 ?; [1 a
    / p* q+ F& q3 c" D! r
  • ( |; j) @% \+ U; S3 B5 x+ D

    RT-FOTA使用正点原子的探险者开发板,如果要运行到其他目标板,可能需要修改相关设置;

    7 H/ b1 T8 Q3 l
  • 4 o% R- e: O7 Z4 a9 ?
  • 3 j+ e+ I' ~. x, }( m

    代码中使用的硬件有usart0、spi0、PE4(key0)、PF9(led0);

    ' Q- z* I; T3 y
  • ' C8 P; H5 A6 ?8 M6 f" R
  • 由于业余时间开发,文档逐步完善,但只要有一定编程基础的朋友,开代码注释即可知道如果进行相关修改;
  • 9 i, h+ R6 b6 `! e1 F) a* y4 A
. f: Y- l/ z1 C* B/ B

联系人信息

- C, H* |0 u/ ]% ^8 s& G- H( W

维护人: 王希

% w8 R: l( F/ f1 x) E2 [
) @$ b' l) D) ?/ i
shell.png
poweron.png
pack1.png
dir.png
shell.png
poweron.png
pack1.png
dir.png
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
发表于 2019-12-3 05:05:59 | 显示全部楼层
完成版的使用 可以做成软件包,维护和使用更方便
使用道具 举报 回复
发表于 2019-12-3 08:55:08 | 显示全部楼层
在哪里可以下载?
使用道具 举报 回复
发表于 2019-12-3 09:02:47 | 显示全部楼层
不错哦,有人把bootload开源出来支持下
使用道具 举报 回复
发表于 2019-12-3 09:06:14 来自手机 | 显示全部楼层
https://gitee.com/spunky_973/rt-fota
使用道具 举报 回复
发表于 2019-12-3 09:10:08 | 显示全部楼层
感谢分享
使用道具 举报 回复
发表于 2019-12-3 09:16:17 | 显示全部楼层
这个厉害了
使用道具 举报 回复
发表于 2019-12-3 09:21:09 | 显示全部楼层
支持一下!
使用道具 举报 回复
发表于 2019-12-3 10:09:10 | 显示全部楼层
本帖最后由 hnhebing 于 2019-12-3 10:11 编辑 / ]* a; e% w- S; B' M

/ F0 ~! l1 L: Q: ?5 T编译出来代码大小75K byte, 占用资源有点大, 管方代码<30K ,有优化空间?
; x' B7 i/ ]# J
使用道具 举报 回复
发表于 2019-12-3 10:23:20 | 显示全部楼层
hnhebing 发表于 2019-12-3 10:09$ k- D, s, w0 Q2 [4 F
编译出来代码大小75K byte, 占用资源有点大, 管方代码

: u0 Y$ M) T5 ], _* \6 ]/ \/ `7 m当然可以优化:
8 g0 }3 s) {  e( l6 @# O6 A6 t+ ]1. 编译选项变为-o3;1 d* M- N' |( O, Y1 d
2. 根据你的实际需求,可以屏蔽选择一种压缩方式:falslz和quicklz,或者不需要代码加密等
, d! O% k  e" c+ M& _: k$ ?+ y3. 根据需求可以裁剪finsh相关功能,比如密码功能;
0 ^9 g1 H0 [4 g; P8 a4. 删除ymodem功能,放在应用代码中实现。
: g) s/ L6 t+ _* J/ M& o. c总之,源码在手,根据自己的需求来进行改进。我记得最小的方式应该可以裁剪在32K以内。/ ]2 @. n3 z6 O* P+ x# M8 g
2 z& w! W0 B  Z) q- i3 f
春节有空了,我会把优化项罗列出来,进行可配置。目前这个版本是全功能的。
使用道具 举报 回复
发表于 2019-12-3 10:35:03 | 显示全部楼层
nice 我看好你哦!
使用道具 举报 回复
发表于 2019-12-3 10:43:34 | 显示全部楼层
NICE,目前RTT的不支持H7,正好看看楼主的这个能不能在STM32H7上实现。
使用道具 举报 回复
发表于 2019-12-3 11:57:55 | 显示全部楼层
whj467467222 发表于 2019-12-3 10:43
) X$ z" |" p$ B- a; H+ mNICE,目前RTT的不支持H7,正好看看楼主的这个能不能在STM32H7上实现。

0 T$ C/ z0 k& c8 j+ N( C5 Q8 p肯定可以啊,在H7的BSP的nano基础上,把application目录里面文件加入到你的工程即可。但是串口、LED和按键要根据你的板子进行改动。
使用道具 举报 回复
发表于 2019-12-3 12:08:50 来自手机 | 显示全部楼层
6666666666
使用道具 举报 回复
发表于 2019-12-3 13:06:06 | 显示全部楼层
感谢分享,学习一下。
使用道具 举报 回复
发表于 2019-12-3 14:15:56 | 显示全部楼层
支持
使用道具 举报 回复
发表于 2019-12-3 15:42:38 | 显示全部楼层
赞一个,支持!   hash_code算法如何用的,群内大佬支持下!
使用道具 举报 回复
发表于 2019-12-3 17:33:53 | 显示全部楼层
手上有个16k以下的boot
使用道具 举报 回复
发表于 2019-12-3 17:40:08 | 显示全部楼层
也是rt-thread还是寄存器应用
使用道具 举报 回复
发表于 2019-12-4 11:09:44 | 显示全部楼层
gideon518j 发表于 2019-12-3 17:33/ N' T) r6 X4 K' `
手上有个16k以下的boot

6 N; R! g9 x( c" X- u6 r) qFINSH的代码空间比较大,不加FINSH功能,代码容量应该会小一些。另外代码支持裁剪,目前是全功能的,两种压缩代码和加密代码都是使能了的。根据具体应用可以在rtconfig.h中进行设置。
使用道具 举报 回复
发表于 2019-12-4 11:10:01 | 显示全部楼层
hnhebing 发表于 2019-12-3 17:40
9 m7 q: U- |9 w也是rt-thread还是寄存器应用
9 O* k3 R! S/ z
基于RT-Thread nano的应用
使用道具 举报 回复
发表于 2019-12-4 11:10:46 | 显示全部楼层
hnhebing 发表于 2019-12-3 15:42
; _& p9 n- b& I+ H赞一个,支持!   hash_code算法如何用的,群内大佬支持下!

: M) y) O: @( _! o同问,暂时不清楚RTT官方hash_code的计算算法。
使用道具 举报 回复
发表于 2019-12-4 11:14:44 | 显示全部楼层
HelloBye 发表于 2019-12-3 05:05
; g1 x" f  U4 J- `- V  k) h% y: t2 W完成版的使用 可以做成软件包,维护和使用更方便

) K& u. q! k) a这个建议倒是可以哈,我思考下,春节期间有时间弄一下。
使用道具 举报 回复
发表于 2019-12-4 17:18:01 | 显示全部楼层
真的有大神把我一直想做还没做的事 做了。。。
使用道具 举报 回复
发表于 2019-12-4 18:55:06 | 显示全部楼层
大佬牛逼!
使用道具 举报 回复
发表于 2019-12-5 15:50:08 | 显示全部楼层
7位QQ号,一定是个工作经验丰富的大佬。
使用道具 举报 回复
发表于 2019-12-5 20:24:48 | 显示全部楼层
这个必须顶起,完美解决当今boot开发难的痛点
使用道具 举报 回复
发表于 2019-12-6 08:52:44 | 显示全部楼层
这个可以有 6666666
使用道具 举报 回复
发表于 2019-12-19 10:49:54 | 显示全部楼层
咋这么牛逼呢相当厉害
使用道具 举报 回复
发表于 2019-12-19 11:16:24 | 显示全部楼层
给楼主点赞!
使用道具 举报 回复
发表于 2019-12-19 12:47:05 | 显示全部楼层
在当前形势下,单片机flash空间已经不是主要限制因素了,这种全功能的boot还是有很大用处的。
使用道具 举报 回复
发表于 2019-12-21 19:50:22 | 显示全部楼层
Summer_gift 发表于 2019-12-19 11:16" ^4 t2 }! J0 Z
给楼主点赞!
8 t0 p! k: r2 K4 i
我这个算是盗版你们的了
使用道具 举报 回复
发表于 2019-12-21 20:49:04 | 显示全部楼层
这篇发布很重量
使用道具 举报 回复
发表于 2019-12-21 23:06:53 | 显示全部楼层
这个老NB了,至此LZ
使用道具 举报 回复
发表于 2019-12-23 09:41:04 | 显示全部楼层
你这让官方情何以堪
使用道具 举报 回复
发表于 2020-1-10 10:01:11 | 显示全部楼层
我怀疑楼主是内部人员
使用道具 举报 回复
发表于 2020-1-10 14:21:38 | 显示全部楼层
灰大狼mk 发表于 2020-1-10 10:01
: `) A6 L1 ^6 R我怀疑楼主是内部人员
1 S% }, w1 |& R( p+ z. P# C
这并不是内部人员
使用道具 举报 回复
发表于 6 天前 | 显示全部楼层
我夏了夏天 发表于 2020-1-10 14:21* k. v' f4 U( J7 g/ M
这并不是内部人员

% i( E0 H9 V3 Y- G  h一直想问下原作者,你们HASH_CODE是怎么算出来的啊?
使用道具 举报 回复
发表于 6 天前 | 显示全部楼层
Spunky 发表于 2020-1-13 16:21) n& Q) @0 q9 x; o" B8 S: ~# i
一直想问下原作者,你们HASH_CODE是怎么算出来的啊?
  Q' N  F2 Q- f  }: x/ x
你指的是用什么哈希算法?
使用道具 举报 回复
发表于 3 天前 | 显示全部楼层
我夏了夏天 发表于 2020-1-13 16:32% w6 T' v, H  Y$ Q& ]5 ^
你指的是用什么哈希算法?

6 k$ d/ ^" G! j- L5 f0 R& _1 z是的,就是那个HASH_CODE是什么哈希算法算出的
使用道具 举报 回复
发表于 前天 10:05 | 显示全部楼层
Spunky 发表于 2020-1-16 22:237 N% a  y$ \! ~, O
是的,就是那个HASH_CODE是什么哈希算法算出的
$ v- k/ t. F$ H& y# v7 l: v
你在网上找一个通用的就可以啦
使用道具 举报 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|RT-Thread开发者社区 ( 沪ICP备13014002号-1

有害信息举报电话:021-31165890 手机:18930558079

© 2006-2019 上海睿赛德电子科技有限公司

Powered by RT-Thread

快速回复 返回顶部 返回列表