找回密码
 注册
关于网站域名变更的通知
查看: 301|回复: 1
打印 上一主题 下一主题

Cortex-M/R 内核启动流程之退出阶段

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-9-25 15:50 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 uperrua 于 2020-9-25 15:52 编辑 2 |) E4 J$ n3 J5 Z9 j* f
( W- K1 N8 h6 j) `1 f
  通常,嵌入式应用程序的执行永远不会结束。 如果推出了,则必须定义正确的结束行为。  w' ~$ M/ g1 M/ N
  要以受控方式终止应用程序,请调用标准C库函数之一 exit,_Exit,quick_exit 或 abort,或从main 返回。 如果从main 返回,则自动执行 exit 函数,这意味着调用静态和全局变量的 C++ 析构函数(仅限C ++)并关闭所有打开的文件。
) p2 ?. T0 C6 r  Q0 g  当然,如果程序逻辑不正确,应用程序可能会以不受控制的异常方式终止 - 系统崩溃。. Z1 P1 j/ g8 P3 h2 m1 v

5 `: [- N3 L. F" a; M' I
- R0 F; z6 w/ D* E) Z7 v; e/ V* D" }( {应用程序可以通过两种不同方式正常终止:) c: J6 w/ k6 S# n6 b

2 D4 P' {" B8 e4 H
  • Return from the main function
  • Call the exit function.. L3 f; R+ U+ u" w- ]5 ^

+ V- ]7 X9 v, P7 Z! a: _) h  因为 C 标准声明这两个方法应该是等价的,所以如果main()函数返回,系统启动代码会调用exit() 函数。传递给exit()函数的参数是main()的返回值。
* W# m3 N0 Y' A5 p% f7 C2 C默认退出函数用C语言编写。它调用一个小的汇编程序函数_exit,它将:) X/ d% a8 p9 r) t/ ~) w' s
1 T( h# _. |1 K5 Z
  • 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.
    ( x* Z2 n6 ~: M( `/ ]
7 |( }( A) I+ M+ V2 e* `
  应用程序也可以通过调用 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的函数。! n  P3 g  s2 e2 \5 J- }
  如果您希望应用程序在退出时执行任何额外操作,例如重置系统(如果使用atexit是不够的),您可以编写自己的__exit(int)函数实现。2 g' V8 d4 k! D  m# D- g

  G1 I9 k  \  }0 R$ j( G
* Q0 E0 x3 E  K5 o9 [) S2 q启动相关函数
% ~! `. u3 {. K7 i0 s* g& b: Y  在基于 ARM 的启动流程中,我们介绍了各启动相关的函数全部位于 ARM 编译套件的库文件中。IAR 则直接提供了相关函数的源代码,源码使用汇编语言编写!
! X3 o, y, l, J0 K* m% a; Q: Q- b1 I  处理启动和终止的代码位于源文件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下面的文件如下图所示:* v, Z- z# W! v$ }  N" W& i  S6 I

) ~# L; E$ h: l' }8 L$ i, V
6 j! @6 N; I8 N7 \8 B8 |1 v& o9 G! J" @+ A) v3 m6 E) b/ q; i% C( m
关于 Thumb 指令的这里我们暂不说明
  i3 |& w, [9 Z% X2 i) q4 G" _# |
" I. y  V: G, X" X: C前面我们已经分析过,第一个需要调用的函数是__iar_program_start,该函数就位于cstartup.s这个文件中!
+ P' D8 Q/ g- J% }& i; M& d- Z$ s! o1 @

$ w# E3 }" S& C/ q) ?$ m0 K启动示例分析
/ y) ^- e/ ]) z, I" v% @+ h1 o
% C. a( Z2 [0 h; s5 V* X下面我们以STM32F373CB片子为例,看看其在 IAR 中调试时的汇编代码。直接进调试模式,注意:需要将 设置 -> 调试器 -> Run to main 去掉,如下图:
) p. a3 B( [( F) M- {
, u$ H& ]" T: A( h' m4 x/ z  V$ G ! @4 k; j  z; ~) a* H

, t6 z- D4 }% T: n7 @: z然后 直接进入调试模式,首先看看终端向量表部分:5 n6 C6 M0 M6 D7 m7 o
" y2 K( \! h5 a: G6 h

# b& t. B+ T3 y( O2 \- i * j5 V( ]! p& d, x6 n! {
/ [% R- j2 o- m2 d
符合前面文章介绍的 Cortex-M/R内核的规定!接着我们看到的就是复位中断的服务函数+ v6 h! U% H# N- s5 d

9 B' S, s3 Y$ }, W    0x8003558: 0x04000401     DC32      0x4000401 (67109889)
; h* N7 b. s6 q) D5 U2 l    0x800355c: 0x08000c77     DC32      USER_DLT645ReqAddr
1 s4 H& N2 H0 O    0x8003560: 0x00000000     DC32      0x0 (0)1 ]5 P9 x# f/ w$ Y9 r( w1 g
    0x8003564: 0x04a01101     DC32      0x4a01101 (77598977)" Z  o8 n) ~9 M8 A3 j0 b
    0x8003568: 0x08000ca1     DC32      USER_DLT645ReqUpGrade
8 H/ _: C/ F) J7 n1 p5 B& g    0x800356c: 0x00000000     DC32      0x0 (0)
0 a( Q1 \2 S; g        LDR     R0, =SystemInit9 @' S6 b5 I9 r
Reset_Handler:& R* T7 ~+ L, q) k
    0x8003570: 0x4801         LDR.N     R0, [PC, #0x4]          ; SystemInit
; ]8 c$ y/ w3 o+ s4 J* {8 ^" j        BLX     R0
$ H, K3 Q+ h) O% ^    0x8003572: 0x4780         BLX       R0                ; 这里跳转到 SystemInit 这是ST提供的+ a+ V6 M. Z5 L: ~- N0 q
        LDR     R0, =__iar_program_start( Z$ o) d  A+ s0 C
    0x8003574: 0x4801         LDR.N     R0, [PC, #0x4]          ; __iar_program_start; b( B: `* O. p9 o
        BX      R08 ?1 @$ b# |) R, n! I
    0x8003576: 0x4700         BX        R0                ; 这里跳转到 __iar_program_start
; U: p9 ?& P; ?* P& V! ~, A  w        SECTION .text:CODE:REORDER(1)
* K' y. m$ p  {# j2 B" s2 e5 L8 A    0x8003578: 0x08003195     DC32      SystemInit
; X8 n9 `& ~+ r+ U( H3 G        SECTION .text:CODE:REORDER(1)
& Y# _, I4 u9 u$ F3 p- a    0x800357c: 0x08003581     DC32      __iar_program_start) C5 G& L. W+ O5 _
__iar_program_start:! R9 F4 R. ^/ w- k
    0x8003580: 0xf3af 0x8000  NOP.W
- I  w! M5 J6 _1 u& m/ f    0x8003584: 0xf3af 0x8000  NOP.W" |7 b" c* Y( v1 p( |
    0x8003588: 0xf7ff 0xffc2  BL        ?main                   ; 0x8003510 重点就在这个函数,, S8 O  O3 G0 N/ [' M+ o5 Q
    0x800358c: 0x11111111     DC32      0x11111111 (286331153)& m3 ~+ z) Y: |1 m* u
    0x8003590: 0x00001111     DC32      0x1111 (4369)
5 T, E, a* c8 p2 z7 X    0x8003594: 0x90           DC8       144                     ; '.'3 d- a4 M4 K- D* ?* s3 {% H  Q  l: M; a. O
    0x8003595: 0x00           DC8       0                       ; '.'7 J& h( I. N9 S7 }3 v: H4 e
    0x8003596: 0x00           DC8       0                       ; '.', O5 n- i/ S4 D2 x
    0x8003597: 0x00           DC8       0                       ; '.'
4 ?! w0 D8 J% I  u' N( v% u        B NMI_Handler$ `( J, V  s1 D. F7 d5 ]
    0x8003598: 0xf7ff 0xbf6a  B.W       NMI_Handler             ; 0x8003470. i6 l* V+ O: T9 u
    ; 后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!, h0 }2 c+ e7 b* X" Z$ D
5 i$ w2 \) _/ O, l! ?0 M% N; }
1 T* O7 ^  Q8 q7 G
从上面的汇编代码可以看出,__iar_program_start 跳转到了一个叫做?main的符号处,代码如下:3 q! z5 H" L8 K7 o0 j

5 s. }; j! T  y- `% O    0x80034c8: 0xb510         PUSH      {R4, LR}) O$ Q+ G* Z0 X9 V1 ~
    0x80034ca: 0x4907         LDR.N     R1, [PC, #0x1c]         ; 0x8 (8)
! _, j: `+ b  n  B" N; k    0x80034cc: 0x4479         ADD       R1, R1, PC
" u8 v2 G7 K# G  _. f: o# r    0x80034ce: 0x3118         ADDS      R1, R1, #24             ; 0x183 B" e0 `8 B! s- {; f
    0x80034d0: 0x4c06         LDR.N     R4, [PC, #0x18]         ; 0x24 (36)
  k9 H* u% `) s' i3 ?( |    0x80034d2: 0x447c         ADD       R4, R4, PC" v; S7 M2 j# Y8 D& O  z
    0x80034d4: 0x3416         ADDS      R4, R4, #22             ; 0x16
- [  u+ N& h2 k5 o1 h0 d0 N    0x80034d6: 0xe004         B.N       0x80034e2! S; a; [& Y2 d% H1 H$ R
    0x80034d8: 0x680a         LDR       R2, [R1]; @- T, [# Q8 W, v4 M* V, Z
    0x80034da: 0x1d08         ADDS      R0, R1, #4+ I! m. D1 [: q( a, q6 H+ R
    0x80034dc: 0x4411         ADD       R1, R1, R2  T* c+ U5 A$ H# \5 m$ ~5 g3 Z* j, @
    0x80034de: 0x4788         BLX       R1+ O5 W  s6 D5 _- m
    0x80034e0: 0x4601         MOV       R1, R09 ]2 L/ V8 `# z8 h
    0x80034e2: 0x42a1         CMP       R1, R4
1 V* y. o# k: E1 ?. K, @) E    0x80034e4: 0xd1f8         BNE.N     0x80034d8/ d" r* u" i& e, l- u
    0x80034e6: 0xbd10         POP       {R4, PC}2 a' Y, B$ V- u, O
    0x80034e8: 0x00000008     DC32      0x8 (8)
2 ?& J9 n5 s3 O" s4 U9 J8 u  {    0x80034ec: 0x00000024     DC32      0x24 (36)$ q0 A$ h5 Z& W- Q
Region$$Table$$Base:# _$ A. x  F. I! A
    0x80034f0: 0xffffdc57     DC32      0xffffdc57 (-9129)
  B' p% b/ P2 `) R- C) y# s8 r    0x80034f4: 0x0000085c     DC32      0x85c (2140)7 Z$ }2 N2 c+ N8 a7 P
    0x80034f8: 0x20000588     DC32      Uart1Info' Q2 e* [+ a9 a. f4 k/ v
    0x80034fc: 0x00000000     DC32      0x0 (0)+ @3 \+ u$ ^+ u9 M
    0x8003500: 0xffffdadf     DC32      0xffffdadf (-9505)
3 j( |* F0 ^/ s* C3 ?1 c! Y# Q    0x8003504: 0x000001b8     DC32      0x1b8 (440)
, N$ t  T* G# F3 z% _; p    0x8003508: 0x0000010c     DC32      0x10c (268)" }- l2 o3 U5 V" g1 u" V; x
    0x800350c: 0x20000000     DC32      UpGradeCtrl/ C0 A7 }$ P$ f) v1 I& l+ ^" a
?main:
5 Y6 _- `7 E+ X7 j/ RRegion$$Table$$Limit:: L5 y2 B2 A3 M9 Y* k# F
__cmain:
2 O% J: I: E' _; y    0x8003510: 0xf000 0xf80d  BL        __low_level_init        ; 0x800352e
! n% N3 P& N7 h8 ^# C  c    0x8003514: 0x2800         CMP       R0, #0" g. _! H; q" i, R
    0x8003516: 0xd001         BEQ.N     _call_main              ; 0x800351c) X* w/ E5 v& f/ J# A9 F' i
    0x8003518: 0xf7ff 0xffd6  BL        __iar_data_init3        ; 0x80034c8) Y+ a4 }) v8 Z) x) }
_call_main:
; f4 q; e7 \* S3 ~4 V' g    0x800351c: 0xf3af 0x8000  NOP.W
9 w4 k" z, d7 s% S: P8 [    0x8003520: 0x2000         MOVS      R0, #0& y; |! s8 c/ G  R8 H
    0x8003522: 0xf3af 0x8000  NOP.W
( |" }. z8 G1 M2 p6 q! ?+ S+ N- B    0x8003526: 0xf7ff 0xff2b  BL        main                    ; 0x8003380% O" f& l7 I( g: t+ U8 k1 S
_main:+ A: W" h1 Z; E& h
    0x800352a: 0xf000 0xf802  BL        exit                    ; 0x8003532
! K" @. U6 F/ N+ D* P, @* c__low_level_init:( w4 T: R% g/ W. z0 g% y5 T
    0x800352e: 0x2001         MOVS      R0, #1
/ N1 V3 Y% H$ d* Q    0x8003530: 0x4770         BX        LR" j. A  ]2 h! J# R, ~4 f
exit:' N: `& |* u  g9 \% t) o, f" g
    0x8003532: 0xf000 0xb801  B.W       _exit                   ; 0x8003538, \+ b( Z0 F; ]; h: M5 J
    0x8003536: 0x0000         MOVS      R0, R0
& I4 L$ R* G+ |! C_exit:/ l1 n. U, ]; _. w9 Z* A
    0x8003538: 0x4607         MOV       R7, R0! O3 Q' F, g& ^: H8 `% |0 H3 [6 d( G
    0x800353a: 0x4638         MOV       R0, R74 k6 N$ n: {: ~$ ]3 i
    0x800353c: 0xf000 0xf802  BL        __exit                  ; 0x8003544& M. f0 N4 ~7 n# S9 x
    0x8003540: 0xe7fb         B.N       0x800353a& ^1 o# O4 t; `6 a/ d5 m
    0x8003542: 0x0000         MOVS      R0, R0
3 O( R1 K4 }  n/ B+ @. {) r9 P% X__exit:
2 P- c1 c! ?+ K7 a1 L4 I    0x8003544: 0xb580         PUSH      {R7, LR}
! p4 o5 m6 D' C    0x8003546: 0xf3af 0x8000  NOP.W
% ?1 R. T0 v5 T% h, s3 d: q& @    0x800354a: 0x4a02         LDR.N     R2, [PC, #0x8]          ; 0x20026 (131110)6 T; A4 h# E. X
    0x800354c: 0x0011         MOVS      R1, R2* o. A; g2 X# \9 c8 P
    0x800354e: 0x2018         MOVS      R0, #24                 ; 0x18
& i: b. V0 _) ]: [    0x8003550: 0xbeab         BKPT      #0xab
  O$ H, I# B$ k3 O) [; A" Y    0x8003552: 0xe7fb         B.N       0x800354c/ j- m$ `" j6 O0 {5 w: [3 o5 O
    0x8003554: 0x00020026     DC32      0x20026 (131110)& F6 j. D& P4 i2 R$ s' O- j! d3 T" M
; 后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!  S2 b$ f; }  J3 K& @3 o

7 X! X" p" c/ w3 b  w. p5 \
, \5 \: B7 p" z+ u
6 F0 r; [4 b8 N  C, S( a
$ r1 ^" G1 p# x0 f* }3 |  J7 @, S
  • TA的每日心情
    慵懒
    2020-6-13 15:46
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2020-9-25 16:35 | 只看该作者
    Cortex-M/R 内核启动流程之退出阶段
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-6-27 02:09 , Processed in 0.093750 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

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