|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 uperrua 于 2020-9-25 15:52 编辑 $ W; e: W# w, s0 t* G2 _( J, P/ G
3 Z+ n! G+ e3 j/ u' M, {7 r- ]
通常,嵌入式应用程序的执行永远不会结束。 如果推出了,则必须定义正确的结束行为。
$ `% S: \1 y* Q7 a. d, e 要以受控方式终止应用程序,请调用标准C库函数之一 exit,_Exit,quick_exit 或 abort,或从main 返回。 如果从main 返回,则自动执行 exit 函数,这意味着调用静态和全局变量的 C++ 析构函数(仅限C ++)并关闭所有打开的文件。
- S3 n. I. J* O0 A5 a 当然,如果程序逻辑不正确,应用程序可能会以不受控制的异常方式终止 - 系统崩溃。$ t# n' n5 d" |8 y% Y. {: A
, T Y/ ~# c5 y1 u4 j4 u- h8 W5 p
" i8 b$ l6 m3 t% h6 s0 Y: C应用程序可以通过两种不同方式正常终止:
! }) a, v( m- G& `! L9 n$ o# Y1 [" h
- Return from the main function
- Call the exit function.( R3 O0 k- `* ]& M! ]# ~$ g
9 X* ~2 p, c; Q4 X( o6 C2 K
因为 C 标准声明这两个方法应该是等价的,所以如果main()函数返回,系统启动代码会调用exit() 函数。传递给exit()函数的参数是main()的返回值。
1 X" {3 d3 G( u; {/ H默认退出函数用C语言编写。它调用一个小的汇编程序函数_exit,它将:
8 b( P1 X0 [- r9 U) b- C4 z9 x( F) {8 m# H( o4 ^: A
- Call functions registered to be executed when the application ends. This includes C++ destructors for static and global variables, and functions registered with the standard function atexit. See also Setting up the atexit limit, page 110.
- Close all open files
- Call __exit
- When __exit is reached, stop the system.
% J) K. o. J2 f, {+ c7 O% e- |
5 ]# K1 {5 |" q7 `" U8 a& w 应用程序也可以通过调用 abort,_Exit 或 quick_exit 函数退出。中止函数只是调用__exit来暂停系统,并且不执行任何类型的清理。The _Exit function is equivalent to the abort function, except for the fact that _Exit takes an argument for passing exit status information._Exit函数等同于 abort 函数,事实上,_Exit接受一个参数来传递退出状态信息。The quick_exit function is equivalent to the _Exit function, except that it calls each function passed to at_quick_exit before calling __exit. quick_exit函数等同于__Exit函数,只是它在调用__exit之前会刁艳红每个传递给_quick_exit的函数。
% s ^& E( j6 e 如果您希望应用程序在退出时执行任何额外操作,例如重置系统(如果使用atexit是不够的),您可以编写自己的__exit(int)函数实现。
. A8 G$ p; V- d
p3 ~* z2 z9 d) L8 U9 I' T2 f9 I' e( G6 _& A! E& l2 Z
启动相关函数
2 L2 w) J0 ~' F8 L0 W 在基于 ARM 的启动流程中,我们介绍了各启动相关的函数全部位于 ARM 编译套件的库文件中。IAR 则直接提供了相关函数的源代码,源码使用汇编语言编写!
6 k3 a, A# g1 L" U1 | 处理启动和终止的代码位于源文件cstartup.s,cmain.s,cexit.s中,这些文件位于arm\src\lib\arm 或 arm\src\lib\thumb目录中(针对 Cortex-M的 thumb 指令)和位于arm\src\lib\runtime目录中的low_level_init.c。其中,arm\src\lib\arm下面的文件如下图所示:3 q' R) p' K: O, f
1 s @8 Q7 D! x' ]
) W& R( b3 g: P1 f7 K3 |4 D# L, E3 Z% i- F# w$ t$ {
关于 Thumb 指令的这里我们暂不说明
' }: `! d4 E7 b& F' d A! b
" o: r8 n5 V/ J( g8 ^前面我们已经分析过,第一个需要调用的函数是__iar_program_start,该函数就位于cstartup.s这个文件中!
9 \4 f1 c$ D' r" Z
9 w# \: O" k' M+ C) n8 L5 {2 m
# {' j. o' ^- R启动示例分析
3 a+ Y/ d0 D. U' ~9 `2 G, ?
/ ]+ N& d$ I4 h2 F2 N下面我们以STM32F373CB片子为例,看看其在 IAR 中调试时的汇编代码。直接进调试模式,注意:需要将 设置 -> 调试器 -> Run to main 去掉,如下图:
0 x: s6 f& s/ Q' M
5 @- `- R# x# i7 w& b5 P! E# p
0 k7 s9 _8 K) M9 t" a$ k
0 R# \. v! b6 Y6 G0 c然后 直接进入调试模式,首先看看终端向量表部分:1 `9 @' M% c* I6 v4 Z% W6 l1 M3 o
4 j5 ~, f* H# `0 y5 D
# @/ W9 y8 y% P) N. \4 B( ]' A/ _
" h6 @4 R# O6 ~0 K! m
; |6 s. ]/ h2 e" i3 m4 S% ]# i' z
符合前面文章介绍的 Cortex-M/R内核的规定!接着我们看到的就是复位中断的服务函数 p7 L: t7 M! Y0 o
* a: A6 ]7 b# l# t
0x8003558: 0x04000401 DC32 0x4000401 (67109889)
+ w/ G. {9 x. H1 o' ~ 0x800355c: 0x08000c77 DC32 USER_DLT645ReqAddr; A7 m- ]& b* z4 f
0x8003560: 0x00000000 DC32 0x0 (0)
1 e+ o* F& ~7 X' W 0x8003564: 0x04a01101 DC32 0x4a01101 (77598977)
! I2 w: Z5 b) \3 Z! U, u' g: q& y 0x8003568: 0x08000ca1 DC32 USER_DLT645ReqUpGrade# B( T8 O! b: A1 O: U( b1 w
0x800356c: 0x00000000 DC32 0x0 (0)7 |5 I# b( b; p/ B1 d: A" @
LDR R0, =SystemInit- O3 E5 ~% H3 C0 @! u( h9 D
Reset_Handler:
- k9 i/ i: f1 ^ m |& J* K 0x8003570: 0x4801 LDR.N R0, [PC, #0x4] ; SystemInit P8 F: N# ~7 L" w% T
BLX R0* F5 j) I/ V1 J; O; o
0x8003572: 0x4780 BLX R0 ; 这里跳转到 SystemInit 这是ST提供的
+ B3 u( _! m( | LDR R0, =__iar_program_start; |. n+ ^4 P5 S
0x8003574: 0x4801 LDR.N R0, [PC, #0x4] ; __iar_program_start) p) J1 `6 H8 H4 N7 |$ Q/ V3 M
BX R03 c. l3 _6 x* c+ O. |- ~# z7 e
0x8003576: 0x4700 BX R0 ; 这里跳转到 __iar_program_start
* k( j0 @0 [( P7 H7 V SECTION .text:CODE:REORDER(1)
7 e% W6 b8 t+ O, \ 0x8003578: 0x08003195 DC32 SystemInit
/ ^* L: m0 ^. u SECTION .text:CODE:REORDER(1)
# _( c$ [" [9 ~2 W 0x800357c: 0x08003581 DC32 __iar_program_start
' J: k* g: A) p2 x$ L. S7 |__iar_program_start:0 k3 f0 Y* ]# I6 i. m
0x8003580: 0xf3af 0x8000 NOP.W9 a+ B" w7 B: }1 }
0x8003584: 0xf3af 0x8000 NOP.W7 w( m# m! c; W# P& o
0x8003588: 0xf7ff 0xffc2 BL ?main ; 0x8003510 重点就在这个函数,
. n! Y1 P; u! |5 ]4 M6 h; K 0x800358c: 0x11111111 DC32 0x11111111 (286331153)
+ C! w% K! X7 T$ R% b' T I 0x8003590: 0x00001111 DC32 0x1111 (4369)
. }% I# X2 H1 g& I 0x8003594: 0x90 DC8 144 ; '.'
# [" I$ F$ t; H& r; t; K 0x8003595: 0x00 DC8 0 ; '.'
& c" A: f2 B' E& Q) g: d$ x! |9 L2 r 0x8003596: 0x00 DC8 0 ; '.'6 ?1 t' D0 |7 r- f3 ]
0x8003597: 0x00 DC8 0 ; '.'- C. `2 j8 S. d5 h: [* E
B NMI_Handler
, N0 j" L4 J# n7 X 0x8003598: 0xf7ff 0xbf6a B.W NMI_Handler ; 0x8003470. o2 {1 m p# k% T% X# u1 G
; 后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!6 l0 ~; P$ S5 U/ J& H O# ?. d
5 n. E& Z" V7 E
+ G4 n; c' `5 H! X/ x5 V从上面的汇编代码可以看出,__iar_program_start 跳转到了一个叫做?main的符号处,代码如下:
/ d* z! k1 _' e% Q+ z" w; i- V( Y' n; a( T' @6 r
0x80034c8: 0xb510 PUSH {R4, LR}
% C! v6 ?" d, r" |" ] 0x80034ca: 0x4907 LDR.N R1, [PC, #0x1c] ; 0x8 (8): F5 m8 x2 M: i2 P& |; I
0x80034cc: 0x4479 ADD R1, R1, PC
: b+ l! [) h/ H$ Y! w 0x80034ce: 0x3118 ADDS R1, R1, #24 ; 0x18; F( D* g6 [; `
0x80034d0: 0x4c06 LDR.N R4, [PC, #0x18] ; 0x24 (36)
: X' k# p1 [7 ~& a1 F( H. F 0x80034d2: 0x447c ADD R4, R4, PC
- K8 R) t0 R$ j, X6 U 0x80034d4: 0x3416 ADDS R4, R4, #22 ; 0x16
2 h) ~# x& {& l9 t; n 0x80034d6: 0xe004 B.N 0x80034e2& a/ @+ f4 i: R# m$ h0 p; w( a
0x80034d8: 0x680a LDR R2, [R1]
' D$ U2 p! Z, A: U. T 0x80034da: 0x1d08 ADDS R0, R1, #41 E! b P/ D3 D) Z5 |) a& b# i
0x80034dc: 0x4411 ADD R1, R1, R2
% G3 K3 _: b4 A! ?, @5 R 0x80034de: 0x4788 BLX R18 ?4 V3 c( a& i0 t/ p8 P8 i8 d
0x80034e0: 0x4601 MOV R1, R0
- Y9 ?: h+ {" B 0x80034e2: 0x42a1 CMP R1, R4
6 X( @/ v6 d: L, o1 F# D3 t 0x80034e4: 0xd1f8 BNE.N 0x80034d8
+ Y# Y9 l* v8 L) B; a7 B; z1 ^ 0x80034e6: 0xbd10 POP {R4, PC}
' r4 D$ r* K1 x; F; n7 j. p# U7 T 0x80034e8: 0x00000008 DC32 0x8 (8)/ ?8 e4 Y# a; ~1 Z& w
0x80034ec: 0x00000024 DC32 0x24 (36)3 Q, o9 e" w3 I# ^$ v
Region$$Table$$Base:
- j% c7 a2 L4 ?$ b5 x: C 0x80034f0: 0xffffdc57 DC32 0xffffdc57 (-9129)
0 H' R+ f4 A; Z* D( I; q1 R1 A" V 0x80034f4: 0x0000085c DC32 0x85c (2140)$ L, H' e2 `' V8 Y& P2 H0 h
0x80034f8: 0x20000588 DC32 Uart1Info" R8 p- X; y1 C6 M
0x80034fc: 0x00000000 DC32 0x0 (0): M$ u' x' G7 d! L, i
0x8003500: 0xffffdadf DC32 0xffffdadf (-9505)
% s m1 n: o1 @, \ 0x8003504: 0x000001b8 DC32 0x1b8 (440)8 B2 }6 n$ A" \( D* x
0x8003508: 0x0000010c DC32 0x10c (268)/ p0 I! K" ^9 P+ Z0 c8 X
0x800350c: 0x20000000 DC32 UpGradeCtrl
f9 s1 Y4 }# S5 d! P5 t- S?main:: F5 m( p- O+ I
Region$$Table$$Limit:
) g' r/ T1 e' ^; N__cmain:5 c& b5 F+ t1 Y
0x8003510: 0xf000 0xf80d BL __low_level_init ; 0x800352e
! \; A1 }. a- M I 0x8003514: 0x2800 CMP R0, #0
( M8 ^) A3 b3 z* u1 ` 0x8003516: 0xd001 BEQ.N _call_main ; 0x800351c- l O2 A' x6 D( J$ y9 X
0x8003518: 0xf7ff 0xffd6 BL __iar_data_init3 ; 0x80034c8
' y( x0 W2 n$ ~* G: C; ~_call_main:
* h6 K+ E% A3 o6 \; N% E3 M 0x800351c: 0xf3af 0x8000 NOP.W# V; X! s- Q; p) h3 a
0x8003520: 0x2000 MOVS R0, #00 J$ ]1 m) P1 f% U
0x8003522: 0xf3af 0x8000 NOP.W
0 }$ _1 p; W/ ?& Z' H 0x8003526: 0xf7ff 0xff2b BL main ; 0x80033806 U$ E+ A$ @5 B
_main:0 B3 F4 |1 S; z1 f7 {
0x800352a: 0xf000 0xf802 BL exit ; 0x8003532
2 ^6 c0 _7 b! o7 A__low_level_init:
( n- B* D8 e# v; w 0x800352e: 0x2001 MOVS R0, #1- ~* m7 O- T' j* @& t2 n6 h3 p( N
0x8003530: 0x4770 BX LR
+ [6 d1 Z4 Q/ f+ S8 T: Y7 jexit:6 |0 Q, k8 X+ C- I0 V S) P
0x8003532: 0xf000 0xb801 B.W _exit ; 0x80035386 p* {& r' H; k
0x8003536: 0x0000 MOVS R0, R0
( ]( e) h6 |/ ~_exit:
4 d8 p+ J- X' `, ~1 t 0x8003538: 0x4607 MOV R7, R0 o+ \: r. U6 q8 P4 `
0x800353a: 0x4638 MOV R0, R75 b% g# ?( _# k! V3 O/ l/ f
0x800353c: 0xf000 0xf802 BL __exit ; 0x8003544
7 u( s% b5 g3 T5 c% ^4 g 0x8003540: 0xe7fb B.N 0x800353a
p( a$ f! o, r$ q 0x8003542: 0x0000 MOVS R0, R0
' X) R2 ^$ ]: P, ?__exit:
2 C. n9 J6 ^1 t! K( K( c# p( f2 T. r 0x8003544: 0xb580 PUSH {R7, LR}6 P8 O4 _5 u' K F' c
0x8003546: 0xf3af 0x8000 NOP.W E( n/ m4 r! U6 e' _
0x800354a: 0x4a02 LDR.N R2, [PC, #0x8] ; 0x20026 (131110)8 h3 t: }! x D8 x0 {$ H
0x800354c: 0x0011 MOVS R1, R2
X% l* i$ K& d$ M- V" {& I& P 0x800354e: 0x2018 MOVS R0, #24 ; 0x18/ Y- f- ~3 e) p* c7 W3 b1 \
0x8003550: 0xbeab BKPT #0xab! p# U* I$ }* Y. Y4 J' c
0x8003552: 0xe7fb B.N 0x800354c
0 K4 U* C7 `. @* e1 z/ R 0x8003554: 0x00020026 DC32 0x20026 (131110)
' W' N: l4 Z: p6 U* m; 后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!
& @& D, c; q5 s6 K) S
* _, \# {& E/ S9 F0 |* d$ V1 k: @# X4 c# \+ m4 n5 E" m# z) t9 c
3 ]3 F# D5 B. M/ q8 }
+ @- U- S" ~3 x3 U
|
|