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

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

[复制链接]

该用户从未签到

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

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
  • 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 22:10 , Processed in 0.187500 second(s), 26 queries , Gzip On.

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

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

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