|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
在ARM程序的开发中,需要大量读写硬件寄存器,尽量缩短程序的执行时间,因此部分初始化代码一般使用汇编语言来编写,比如ARM的启动代码,ARM的操作系统的移植代码等,除此之外,绝大多数代码可以使用C语言来完成。2 n. S; S/ | r( S" d
1 J# |1 I9 Z/ C( `7 S
C语言使用的是标准的C语言,ARM的开发环境实际上就是嵌入了一个C语言的集成开发环境,只不过这个开发环境和ARM的硬件紧密相关。1 g O$ f$ O3 s. t
7 K- ]6 a& k$ s3 A6 f; S1 h) G
ARM使用C语言编程基本规则. Q6 y; E' O4 A& |* b7 l. I
' O0 ?1 i+ r7 S; s% t" m+ Z
在应用系统的程序设计中,若所有的编程任务均由汇编语言来完成,其工作量巨大,并且不易移植。由于ARM的程序执行速度较高,存储器的存储速度和存储量也很高,因此,C语言的特点充分发挥,使得应用程序的开发时间大为缩短,代码的移植十分方便,程序的重复使用率提高,程序架构清晰易懂,管理较为容易等等。因此,C语言的在ARM编程中具有重要地位。
9 ?; W9 k C8 ^% N* S
' M$ f/ O4 ]7 f0 a在ARM程序的开发中,需要大量读写硬件寄存器,尽量缩短程序的执行时间,因此部分初始化代码一般使用汇编语言来编写,比如ARM的启动代码,ARM的操作系统的移植代码等,除此之外,绝大多数代码可以使用C语言来完成。
: w; a; _3 f1 e& z6 C
# h7 S7 ~9 L5 H# ZC语言使用的是标准的C语言,ARM的开发环境实际上就是嵌入了一个C语言的集成开发环境,只不过这个开发环境和ARM的硬件紧密相关。
# c9 Z1 u3 V! w7 Q! I4 x" P, X3 t+ [# b5 B+ R
在使用C语言时,有时要用到和汇编语言的混合编程。当汇编代码较为简洁,则可使用直接内嵌汇编的方法,否则,将汇编程序以文件的形式加入项目当中,通过ATPCS(ARM/Thumb Procedure Call Standard)的规定与C程序相互调用与访问。9 @0 m) [! ?2 [: i1 p$ j# O' Q( ]
7 n4 O4 I) n p O( F' M: k
ATPCS,就是ARM、Thumb的过程调用标准,它规定了一些子程序间调用的基本规则。如寄存器的使用规则,堆栈的使用规则,参数的传递规则等。, ?' ^+ d( y% t# R, T
# d$ { Y1 W; O8 h, r2 O
在C程序和ARM的汇编程序之间相互调用必须遵守ATPCS。而使用ADS的C语言编译器编译的C语言子程序满足用户指定的ATPCS的规则。但是,对于汇编语言来说,完全要依赖用户保证各个子程序遵循ATPCS的规则。具体来说,汇编语言的子程序应满足下面3个条件:
. o5 `' \9 z1 A$ l# M7 g
% P* G' L5 c0 ^$ a" j. 在子程序编写时,必须遵守相应的ATPCS规则;# a7 |8 r4 m" B) b& r
3 D0 V$ O" ^/ V Q. 堆栈的使用要遵守相应的ATPCS规则;
8 V; a! M3 ^# q; {1 b9 P1 ~8 M4 T
4 ?) @1 S# q( }! M5 z. 在汇编编译器中使用-atpcs选项。. ?0 Y+ u3 W8 m% T+ o- g
2 R: M. H: y0 n! X3 r; Z, }9 @
基本的ATPCS规定,详情请见相关PDF文档,简单说明就是:
4 X/ y# m: @+ V: X% }3 D
: R. L% J0 Y: O: j1. 汇编程序调用C程序
. d! S$ E: h$ k
1 I/ X$ e6 w2 Y: @1 F) |# Y. 汇编程序的设置要遵循ATPCS规则,保证程序调用时参数正确传递。" r1 P. A2 p8 t+ q; t9 t- G, X
: ]2 z( ]3 w$ z8 J; T0 x+ G! @. 在汇编程序中使用IMPORT伪指令声明将要调用的C程序函数。
9 X- |7 C5 Z9 H( w0 E
_, K6 l% R6 x; E5 h4 M" h. 在调用C程序时,要正确设置入口参数,然后使用BL调用。" f# J0 T% X; J0 g( O
v6 j& ]- D" @$ x/ b6 ~3 E) [2. C程序调用汇编程序& d2 v/ L( T+ h# B- w
9 V X4 ~1 I8 W+ Y. 汇编程序的设置要遵循ATPCS规则,保证程序调用时参数正确传递。
6 c; g. S4 @: S7 n- I6 ~# {7 I
/ ?+ a$ C: B/ f9 N. 在汇编程序中使用EXPORT伪指令声明本子程序,使其他程序可以调用此子程序。' e4 w0 |8 e$ J3 |. B! S M* C
) t$ D8 w5 l8 e" S0 s; f% |' s* k3 M
. 在C语言中使用extern关键字声明外部函数(声明要调用的汇编子程序)。0 G" Z' B& f3 b3 T8 U- n& U2 I; w
4 b# c! S! ^1 G7 }8 O在C语言的环境内开发应用程序,一般需要一个汇编的启动程序,从汇编的启动程序,跳到C语言下的主程序,然后,执行C程序,在C环境下读写硬件的寄存器,一般是通过宏调用,在每个项目文件的Startup2410/INC目录下都有一个2410addr.h的头文件,那里面定义了所有关于2410的硬件寄存器的宏,对宏读写,就能操作2410的硬件,具体的编程规则同标准C语言。
% w+ n; |" |6 I. L1 V0 A' F1 |# x, R" U& i) J" `4 W( \ }$ T$ T
; M) F) a u6 o, T7 `0 b: @/ R2 n+ A9 ~/ Z
ARM Cortex™ 微控制器软件接口标准(CMSIS:CortexMicrocontroller Software InteRFace Standard) 是 Cortex-M 处理器系列的与供应商无关的硬件抽象层。+ Q( N7 _ T H# x
2 q# S% k- `) @' F0 w: y' y
, m) _4 e4 b6 ]) z3 _4 s$ {6 Y3 G! v4 | G% d; S
9 L, N% ^' L' H$ Q9 Y
6 d! C/ e: a/ d3 c* d1 o3 V$ J基于CMSIS标准的软件架构主要分为以下4层:用户应用层、操作系统及- ?+ j5 D3 G* B1 i& r- s- ]
% X8 U7 N6 r; [中间件接口层、CMSIS层、硬件寄存器层。其中CMSIS层起着承上启下的作用:一方面该层
) t4 y: z, T. q- @2 B" ^ T! b! g5 p( u" M
对硬件寄存器层进行统一实现,屏蔽了不同厂商对Cortex‐M系列微处理器核内外设寄存器; F7 g [' a! J) J2 m6 ?
, @8 d- y6 z. P- b的不同定义;另一方面又向上层的操作系统及中间件接口层和应用层提供接口,简化了应用
! V+ Q& [& z; Y6 _8 P9 K* D$ s$ S0 l
程序开发难度,使开发人员能够在完全透明的情况下进行应用程序开发。也正是如此,CMSIS
: T" E1 B2 V3 i" u( T9 c! Y* l. E1 V9 A+ }1 h
层的实现相对复杂。
4 d4 f: N1 p, n; ?) q X6 ^
' U/ t+ H/ x# D; Z) F6 \) Q9 y! c6 s, }+ b
( |" b& |, S9 K1 D: T- @: rstm32f10x.h:CMSIS 的
8 {+ _' p+ ?: H( O
" H0 [: Y% I2 C+ U# a0 A- t4 |Cortex‐M3 STM32f10xxx微
! J i' V) M5 B6 L8 E
6 Y3 H: K7 _1 J- i4 u3 H控制器外设访问层头文件
3 Q3 r7 t! f" h' R7 t
. E; [4 J) R! t* \- d, dsystem_stm32f10x.h :+ X% P+ n" A& D5 m
- [0 I: I" X9 F6 |# s5 {
CMSIS 的 Cortex‐M31 ^1 e7 C1 n1 J. q7 P1 i
' T4 J- Y& {! r1 d2 A
STM32f10xxx 微控制器外
0 |( l" u9 z0 P2 m& ^9 b$ j
8 g2 k+ G1 a+ Z* I设访问层头文件
6 x7 J( E- V$ y; \
: H9 s4 ?' {' E* }system_stm32f10x.c :
0 v+ `- L( A" B% _% @ [
8 k0 u9 r, a( x9 ?9 K+ `CMSIS 的 Cortex‐M3& D! ?: f) E5 }* U0 v
7 q7 C) t0 J; |! T1 S
STM32f10xxx 微控制器外
; Y. I3 c( t e1 F* Y4 _9 K8 Z u
J! C4 H4 N7 C5 E# E/ ?设访问层源文件( u7 ~& U2 g" c _' e* o4 u5 g d, _
! p& L5 d1 T& o1 j* A0 O- F; ~
- Z( c) v8 t' E; B* O. }
) h/ h d9 A* t6 u首先新建一个项目并设置工具链对应的启动文件,可以使用标准外设库中提供的模板,也可$ z* s6 P0 r& [+ j% z' B
4 c! x$ E4 s/ C" s1 Z+ n以自己根据自己的需求新建。标准外设库中已经提供了不同工具链对应的文件,位于3 v! O2 Z9 Z$ d* l
~& ~/ U& Z" B: Z: y5 O: j2 bSTM32F10x_StdPeriph_Lib_V3.4.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup
: Q h, C6 c: k- z5 U7 m4 [$ x' \' \, i
1 t3 e/ p) a1 k* B
% c5 k, s: y. X8 m7 y( B/ q目录下。
2 ~% d" o k O- G( o8 H5 a$ z, q; }/ H7 U5 a
其次按照使用产品的具体型号选择具体的启动文件,加入工程。文件主要按照使用产品的容$ @; N: G j% W$ i
* g$ \! s) g- W7 ~8 t
量进行区分,根据产品容量进行选择即可。+ P9 ?7 y4 u5 T
7 o' `* k3 X4 T# b7 N
) h8 `; H' ]" ?- b$ z* ~; s" `* N! j8 J9 M9 h6 M
' s3 Y1 {4 f+ X) U- ^2 b: |
' }, q' a7 K: dstm32f4xx_it.h外设中断函数文件 用户可以相应的加入自己的中断程序的代码,对于指向同一个中断向量的多个不同中断请求,用户可以通过判断外设的中断标志位来确定准确的中断源,执行相应的中断服务函数
3 ?! B' g& l5 k* L6 G! a4 K: u│ system_stm32f4xx.c 文件 函数Sysem_ExtMEMCtl,用来配置外部存储器控制器。它位于文件startup_stm32f10x_xx.s /.c,在跳转到main前调用 SystemFrequncy,该值代表系统时钟频率
4 J$ e0 ~# }) W0 k: X. F# B0 d; i/ S+ P2 m2 r$ j' F
) k& [ N- o4 e
0 a3 {1 K: p/ W2 B
/ l$ \7 N$ B/ u6 H& x% R
2 M; y) h4 n& B+ k/ E2 F$ u! mLibraries\STM32F10x_StdPeriph_Driver\下的内容很好理解就是stm32的各个3 u: _1 G# {' s0 i
% P" [% K# G, i* s' w外设模块驱动代码。
6 X8 Z2 Z# ]: T, P9 V( \; v5 A* {& D) q5 E% {8 V$ ?. ^! B0 Q
misc.h和misc.c是和CM3内核有关的NVIC和SysTick的驱动代码。9 b0 j- C* b$ o% C) e' _2 e
: T' P3 \: a$ G5 r
Libraries\CMSIS下是什么呢?cmsis英文全称:CortexMicrocontroller1 w" N5 N9 g9 A( `- p
& v& I4 G+ x9 X9 m3 O1 T0 { ~Software Interface Standard,是Cortex系列处理器硬件抽象层,可以理解为cortex$ b. l6 t4 c, f- M% }& z
# t& H, {, I9 _" b3 t0 T3 ^3 v
内核的软件接口。9 G3 [, M6 B; d% g5 Q. P
' T1 ~7 r1 n5 o: s x6 V& H' z
core_cm3.c, core_cm3.h( V; d, |3 H7 o% ?( P# S1 Q0 T
* X' B( k* {6 G& c; w
它们的目录名为CoreSupport,说明这两个文件是CM3内核支撑文件,其他使
/ e5 ^& {7 P( @+ O1 C4 Y
( J, H, ~, v6 v/ l3 H用CM3内核的芯片也可以用,不一定是stm32。这两个文件用来获取设置CM3内
6 p) z9 Y6 b& { f! K2 {& E) L# G- K8 K4 G& a
核,配置一些内核寄存器。
+ Z4 W! n0 Q+ V+ a2 Q( K5 I2 v _9 n# P: N& H" j
stm32f10x.h, system_stm32f10x.c,system_stm32f10x.h和$ a' a8 x' W* G
9 i5 e, H- t/ M: W' K& h3 xstartup_stm32f10x_hd.s在DeviceSupport目录下,说明这几个文件是和具体的芯( N& Z7 h0 ]0 N% d/ b
! v# G+ |8 o. C) U6 l
片有关的,也就是stm32芯片的支撑文件。其中stm32f10x.h是标准外设库的入口,/ u& i T3 `/ g3 M- o5 ?0 ]- P& \
% [1 r' M% U5 K8 O, n* R
使用标准外设库的代码中必须包含该头文件。system_stm32f10x.c,
9 M% d% W( }" E* Q
7 B% M+ S. H3 W; ]2 asystem_stm32f10x.h这两个文件提供函数用来初始化stm32芯片,配置PLL、系1 N, D' ^ J. ?
$ T3 `# a- ~+ b2 F! o6 D: F* f统时钟和内置flash接口。startup_stm32f10x_hd.s是大容量型stm32芯片的启动$ d/ D0 Q9 {) I7 V+ R
6 F# X7 F+ v+ @0 q" q- n文件# a$ t. t2 w/ O8 W- j0 R$ N2 ]
?% F# b l5 R* F
$ \: ]; S0 S9 R3 h# m
' N. ?8 w! |/ b9 U4 z9 A7 D# _stm32f10x_it.c,stm32f10x_it.h是中断服务程序文件。stm32f10x_conf.h是标
7 P4 D& { M+ d& H1 e0 w! Q
3 U4 i) t( _/ c% L% q0 ]4 `准外设库的配置文件,对于工程中不需要的外设,可以注释掉里面的包含的头文件。
$ w/ U& V# v( S9 y! T: K
4 A$ g& m1 ?/ u. @) p( H这里我建议先仅留下stm32f10x_gpio.h,stm32f10x_rcc.h,misc.h,用到什么再打
9 E7 v+ ]! c% _$ D9 w
/ y% I: G3 S/ B/ Q' `) h0 y' ^开什么,这样编译起来快一点,当然也可都留着。
: B) l. r" I" n/ Y8 _2 C
) ~) r1 Y2 G/ t& {. E* n& l2 ?' S$ g+ O! n! q. q' h
0 D- w3 `1 {1 ~4 K7 a( a% C- w r1 u
|
|