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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
本帖最后由 uperrua 于 2020-9-25 15:52 编辑 + N( i+ H* C' L: ~. @0 t' }

* H" [; ~. k5 o  通常,嵌入式应用程序的执行永远不会结束。 如果推出了,则必须定义正确的结束行为。5 b' I% @6 s$ b  m+ X1 n* X
  要以受控方式终止应用程序,请调用标准C库函数之一 exit,_Exit,quick_exit 或 abort,或从main 返回。 如果从main 返回,则自动执行 exit 函数,这意味着调用静态和全局变量的 C++ 析构函数(仅限C ++)并关闭所有打开的文件。
$ P/ [( O9 ?0 C+ V* z  当然,如果程序逻辑不正确,应用程序可能会以不受控制的异常方式终止 - 系统崩溃。4 I, _, @  D: b" B& a: a

8 n* _2 N+ s6 d8 W7 M
6 g2 K/ _6 C% Q; ]应用程序可以通过两种不同方式正常终止:- T+ B% Q$ v9 L  r4 j
  v/ \; j; a" a& r
  • Return from the main function
  • Call the exit function.
    , g+ x! J" q" Y/ Q
. ?" d" |9 G1 Q2 j
  因为 C 标准声明这两个方法应该是等价的,所以如果main()函数返回,系统启动代码会调用exit() 函数。传递给exit()函数的参数是main()的返回值。
  C6 w5 N4 d! W/ R. v默认退出函数用C语言编写。它调用一个小的汇编程序函数_exit,它将:
2 I( m+ l& c! j' Z* D5 x' m/ @' \; e: M3 P: L. q4 [/ J
  • 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.
    " F- p% g- `8 m/ S! o- @
% h, L8 z' w# 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的函数。. y+ M9 Y9 R7 |( g
  如果您希望应用程序在退出时执行任何额外操作,例如重置系统(如果使用atexit是不够的),您可以编写自己的__exit(int)函数实现。
# ?' Z1 b* q5 ~5 q3 V+ ~& T+ d  q3 `9 g6 A, z$ k. p

' d2 B- [0 a9 k& x启动相关函数
4 K5 I8 ]: X% v. S  在基于 ARM 的启动流程中,我们介绍了各启动相关的函数全部位于 ARM 编译套件的库文件中。IAR 则直接提供了相关函数的源代码,源码使用汇编语言编写!
/ g1 E( H8 K9 D+ v  处理启动和终止的代码位于源文件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下面的文件如下图所示:8 X6 a- Y. c' i# }  q; k
# b4 N' m. Z2 t3 h: l

2 ?' M6 B. B8 L4 \4 @2 A! W+ w. b% [1 D4 B3 V; _& B0 n
关于 Thumb 指令的这里我们暂不说明
- |4 X& p2 {9 E7 t5 b& C& k! k% r$ l/ \6 v( H- D/ t
前面我们已经分析过,第一个需要调用的函数是__iar_program_start,该函数就位于cstartup.s这个文件中!$ Q  w& ^5 `0 H, P8 `* k

" D4 p6 i' p; M. P
+ B3 E( E# g6 U) W  Z# m启动示例分析
# H: Y" K3 u/ z: R9 {5 M  y7 D' S- f' T  ~
下面我们以STM32F373CB片子为例,看看其在 IAR 中调试时的汇编代码。直接进调试模式,注意:需要将 设置 -> 调试器 -> Run to main 去掉,如下图:  ]. Q) G  D4 P$ F% c6 o* R+ ~

8 m% h9 E9 Q- Q7 V- i3 u9 t 7 a' m7 F, L$ \

5 \2 w' B6 r2 o: s  l然后 直接进入调试模式,首先看看终端向量表部分:
/ a7 J1 b; {4 @6 R; v$ Q6 G/ ]5 n5 j# P/ l5 C1 a! g1 B
2 N$ Y8 m8 i3 `" z( _

. |2 t" U  z! c. m, f1 R) p4 U6 B/ c# w1 ]4 M
符合前面文章介绍的 Cortex-M/R内核的规定!接着我们看到的就是复位中断的服务函数
, d% s. F4 D8 ^
5 g( H, _/ l% Q' G$ r4 |4 x    0x8003558: 0x04000401     DC32      0x4000401 (67109889)6 H4 n; ?# i' I% ~
    0x800355c: 0x08000c77     DC32      USER_DLT645ReqAddr
- f2 k& G$ d( W# {+ y6 H    0x8003560: 0x00000000     DC32      0x0 (0)
7 A' g$ [; L5 [& [) q7 f    0x8003564: 0x04a01101     DC32      0x4a01101 (77598977)% c* u4 ^. H+ H3 H4 |6 A
    0x8003568: 0x08000ca1     DC32      USER_DLT645ReqUpGrade
  M2 E8 D* \( g4 F' [6 x. F9 s    0x800356c: 0x00000000     DC32      0x0 (0)0 q" w) e" C; @5 K# V
        LDR     R0, =SystemInit: O! s1 e* w. A
Reset_Handler:: [( b( C. o  H$ ]8 t
    0x8003570: 0x4801         LDR.N     R0, [PC, #0x4]          ; SystemInit: R* V# M; h7 i) {9 I
        BLX     R0
! w& e* z# }$ r- _! L    0x8003572: 0x4780         BLX       R0                ; 这里跳转到 SystemInit 这是ST提供的
, @8 h$ G$ W, n) |7 k% q$ C        LDR     R0, =__iar_program_start4 @. z/ W3 Z+ a2 V0 d) ^& Z
    0x8003574: 0x4801         LDR.N     R0, [PC, #0x4]          ; __iar_program_start. P  g7 o  F3 Y
        BX      R0
) X' {* p# V4 o    0x8003576: 0x4700         BX        R0                ; 这里跳转到 __iar_program_start: U( L. I& v1 ~( J
        SECTION .text:CODE:REORDER(1)
! w2 J" j# N) z  _5 ~    0x8003578: 0x08003195     DC32      SystemInit5 `. ]) \; i) w# M0 I( q8 s. s
        SECTION .text:CODE:REORDER(1)
; J- G, G, p5 _' h8 y    0x800357c: 0x08003581     DC32      __iar_program_start
" x5 s2 X$ e% a. K) x# N  W__iar_program_start:8 l' `1 g# [% t/ y
    0x8003580: 0xf3af 0x8000  NOP.W
4 N+ h* K4 S/ l  X7 t; I    0x8003584: 0xf3af 0x8000  NOP.W) @/ ~5 v8 b- B- _8 U
    0x8003588: 0xf7ff 0xffc2  BL        ?main                   ; 0x8003510 重点就在这个函数,$ V7 N! o. L& ]5 @0 b% H
    0x800358c: 0x11111111     DC32      0x11111111 (286331153)
8 c$ K3 Z9 `0 u& a& D0 z" O* a    0x8003590: 0x00001111     DC32      0x1111 (4369)
5 z  w- n/ s8 w& A, F    0x8003594: 0x90           DC8       144                     ; '.'9 u7 D1 X# o, {$ ]3 }
    0x8003595: 0x00           DC8       0                       ; '.'/ \: u/ g9 i+ h! L# k: ^/ o
    0x8003596: 0x00           DC8       0                       ; '.'. Z3 k9 g1 ^7 Y+ l" G, K8 M6 V
    0x8003597: 0x00           DC8       0                       ; '.'
$ Q1 f) I# ]( v, X6 q3 Y        B NMI_Handler5 p3 k: h: T) s" y% z# Q; M# R
    0x8003598: 0xf7ff 0xbf6a  B.W       NMI_Handler             ; 0x8003470
( ?9 C# \: t; M, {# @5 @/ L- C    ; 后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!  t4 F0 d8 D2 x5 {: {
) N" {2 l# L0 N
# B6 y; U5 Z" D
从上面的汇编代码可以看出,__iar_program_start 跳转到了一个叫做?main的符号处,代码如下:2 ~* n! R6 M) ~5 L9 a) s
# N/ \$ }5 a+ ]3 j" Y1 M
    0x80034c8: 0xb510         PUSH      {R4, LR}
- I& Y. M1 a: P- j    0x80034ca: 0x4907         LDR.N     R1, [PC, #0x1c]         ; 0x8 (8)  P1 A. m) @. {6 s
    0x80034cc: 0x4479         ADD       R1, R1, PC! K: N. Z  y# D
    0x80034ce: 0x3118         ADDS      R1, R1, #24             ; 0x18* H5 _! u: p9 t% l! M
    0x80034d0: 0x4c06         LDR.N     R4, [PC, #0x18]         ; 0x24 (36)
/ N5 G4 O; `8 y( [) j# r    0x80034d2: 0x447c         ADD       R4, R4, PC: L: O6 ~. a2 }: I. `
    0x80034d4: 0x3416         ADDS      R4, R4, #22             ; 0x16
( K4 W! E1 y. Y$ B6 b. Y    0x80034d6: 0xe004         B.N       0x80034e2
6 g2 H" X8 `: O    0x80034d8: 0x680a         LDR       R2, [R1]
6 g# h: Y4 \# ]9 [    0x80034da: 0x1d08         ADDS      R0, R1, #42 P6 e* N. l8 B+ E' t' d0 q
    0x80034dc: 0x4411         ADD       R1, R1, R24 J! P# x8 O! Y, d% v( r
    0x80034de: 0x4788         BLX       R14 G$ ^2 M2 `8 k
    0x80034e0: 0x4601         MOV       R1, R0
2 s7 b. x+ n* x8 z( |0 g$ J  q2 h    0x80034e2: 0x42a1         CMP       R1, R4; z: Q8 ~) o% f# G$ _
    0x80034e4: 0xd1f8         BNE.N     0x80034d85 a$ g/ E! \/ I: H% ?
    0x80034e6: 0xbd10         POP       {R4, PC}
/ I3 v( i5 A, _    0x80034e8: 0x00000008     DC32      0x8 (8)
9 L# _: I9 q( _, H8 E$ a3 J' Q    0x80034ec: 0x00000024     DC32      0x24 (36)
) l# J/ \: W2 tRegion$$Table$$Base:/ B; i$ ]" _; O/ E
    0x80034f0: 0xffffdc57     DC32      0xffffdc57 (-9129)
9 j! U/ {! ~. C' {) X4 T    0x80034f4: 0x0000085c     DC32      0x85c (2140)
" |! }; U+ d7 D, W# [& X    0x80034f8: 0x20000588     DC32      Uart1Info% G/ B! T8 d+ I+ E8 S0 e+ T
    0x80034fc: 0x00000000     DC32      0x0 (0)
3 v. S1 @5 Y+ a7 \7 e6 F" j    0x8003500: 0xffffdadf     DC32      0xffffdadf (-9505)  _% ?' b' n, T3 v- X
    0x8003504: 0x000001b8     DC32      0x1b8 (440)" M2 m/ C, N' T
    0x8003508: 0x0000010c     DC32      0x10c (268); ~1 P- ^) T- Q* U" O
    0x800350c: 0x20000000     DC32      UpGradeCtrl
% x! p* s: ?" G% L?main:
1 V/ \# V! r+ A: BRegion$$Table$$Limit:( h& T+ @3 {* M: O9 I7 s
__cmain:: J+ o; }/ B# b. P& V* N
    0x8003510: 0xf000 0xf80d  BL        __low_level_init        ; 0x800352e+ u* P* t4 e0 ?- H' @5 K
    0x8003514: 0x2800         CMP       R0, #0" s1 d5 `: x* f9 a- J
    0x8003516: 0xd001         BEQ.N     _call_main              ; 0x800351c
' ~" ?! _0 y. z    0x8003518: 0xf7ff 0xffd6  BL        __iar_data_init3        ; 0x80034c83 a1 h! [0 G1 t8 |; E: J
_call_main:
8 a, K0 Z- e% V    0x800351c: 0xf3af 0x8000  NOP.W
: P/ |" t+ }9 j4 {0 B# f" y    0x8003520: 0x2000         MOVS      R0, #0
% a4 j+ E% y  {: V    0x8003522: 0xf3af 0x8000  NOP.W1 J9 G6 n. a" t1 I( L0 h
    0x8003526: 0xf7ff 0xff2b  BL        main                    ; 0x8003380
# s; H& w6 G  T. F/ A0 J( B_main:: F% w$ m) s2 b/ v! L; }- k
    0x800352a: 0xf000 0xf802  BL        exit                    ; 0x8003532
2 T  |0 x& Q* D) Y& ^, W" k: F, i__low_level_init:8 X  o7 \# x7 M) g2 ]3 J
    0x800352e: 0x2001         MOVS      R0, #1
; a' P& ], |$ C3 C! B* c7 O3 l    0x8003530: 0x4770         BX        LR4 W: b2 c: S% Y
exit:
3 `, z8 J. b" o/ Q) i    0x8003532: 0xf000 0xb801  B.W       _exit                   ; 0x8003538" z6 @( V! q( T- d) n2 x
    0x8003536: 0x0000         MOVS      R0, R0
! S, j! A/ X6 E_exit:1 N' f. `4 s. W6 S8 D; T. ]- G/ Y
    0x8003538: 0x4607         MOV       R7, R0
. H# j. H2 b5 ?2 y3 Q5 p! Z    0x800353a: 0x4638         MOV       R0, R7
7 q% S; s0 M- `- j    0x800353c: 0xf000 0xf802  BL        __exit                  ; 0x80035448 h2 Z8 K, G$ t7 u# \4 N5 d6 J& R
    0x8003540: 0xe7fb         B.N       0x800353a
6 \# l9 U0 `9 x: w    0x8003542: 0x0000         MOVS      R0, R0+ F" ~" y6 u! @; ^  G$ S- _  f
__exit:6 d/ W( A; \% p1 Y1 O0 p# H
    0x8003544: 0xb580         PUSH      {R7, LR}
/ S; E6 y" ], O    0x8003546: 0xf3af 0x8000  NOP.W
- ]+ w% s: n' i8 n7 \2 i0 Y! u    0x800354a: 0x4a02         LDR.N     R2, [PC, #0x8]          ; 0x20026 (131110)
% T0 e) `1 u0 @: n; k" L    0x800354c: 0x0011         MOVS      R1, R28 s) U. M$ Y& S! X! r; z, S0 S  Y* ^, F
    0x800354e: 0x2018         MOVS      R0, #24                 ; 0x18
; d2 w1 ]# o8 N# `. R! f3 h    0x8003550: 0xbeab         BKPT      #0xab
1 Y$ {# w# _) R: g8 F- c+ M    0x8003552: 0xe7fb         B.N       0x800354c4 n9 {1 O: a+ r3 Q2 v
    0x8003554: 0x00020026     DC32      0x20026 (131110)6 q+ \6 y: N2 `4 q
; 后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!后面的省略!
: y* i# B/ h" D, A
( i6 w  `3 N9 G2 \
. h6 |3 u: c9 m2 M2 s/ k' _
- c  W6 A" }' T* r$ l8 X4 f# K7 ^/ Z7 k* E. F9 P# j
  • 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-11-24 21:28 , Processed in 0.203125 second(s), 26 queries , Gzip On.

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

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

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