|
STM32Cube LL能高效的原因
5 s2 N: w3 }, i% h; a
2 [& l- k" m" X5 uST的库,有很多巧妙之处,值得大家借鉴。今天就来讲讲STM32Cbue LL库中的一点小知识。
" I$ u- y5 x7 C
- j' @. S* W4 y' E* x3 C3 l8 m1 `$ U! f1 s" d
1写在前面: C0 L1 H4 {1 T" l- s6 l. P
有些应用要求MCU能高效处理,特别是跑一些算法时,对CPU执行效率这一块有要求。
: b( X- X) U. M2 \) I
- M! h$ l8 m) I, D7 r# k; E; p9 k
& X8 w/ s- e: |3 S: G网上有很多文章说STM32Cube HAL执行效率不高,代码量大等问题,导致很多没入门,或初学的朋友产生各种各样的疑惑。( i& H! R, q' R" S8 `1 n
4 `7 L0 z- ~8 J, i5 S. N! Y
6 A' f7 w7 w" r/ M; m& k1 P& z& O承认,HAL相对来说有这些问题,那么与之对应的STM32Cube LL恰好避免了这样的问题。
( {$ I9 ]$ d- ` K" e3 }1 H: y* p' x( p7 v5 C" g
1 {$ r% ?6 Q X I# o& v2LL能高效的原因
. W( p( o* U7 I! q简单总结一下原因:巧妙运用C语言静态的,内联函数直接操作寄存器。
3 f0 \/ F1 b1 t1 m$ |( x' Q$ A- i% n, h! K' B1 W# j
: l3 L1 }4 w# n7 R' Y/ W
当然,这是其中重要的原因,还有一些其它原因,这里不描述。9 v9 r. ]3 z# i1 y8 H% ? [
: F7 f* P) b0 v% _4 B
$ Z% s9 J: m5 D& D1 c! x6 x. M你会在LL库.h文件中发现大量类似,静态,内联函数直接读写寄存器的函数。4 a* z* \6 ] w% e0 N
7 g6 k7 z8 c* [" d6 q0 z: V( k
! W4 B' v( D. j1 e" q比如:读写IO口" A. x5 u# I. N. C. [7 v/ D2 C
( N1 G1 J; B- m# k% p- __STATIC_INLINE uint32_t LL_GPIO_ReadOutputPort(GPIO_TypeDef *GPIOx)
7 O% ~2 X' E$ x$ Q K - {
6 S) E2 ~4 n4 F( s - return (uint32_t)(READ_REG(GPIOx->ODR));
& s: y: q# [* `, _1 k - }& d2 t7 y) c" M- g3 V" o! {
- , c& g* Q0 Y( [6 Z& t9 b
- __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
( ^0 m$ Y3 j! Q/ D - {
& m+ _7 x3 E0 X, A1 Y7 f( k - WRITE_REG(GPIOx->BSRR, (PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU);# g* B4 k1 W' L$ o3 T
- }
复制代码
; {( E7 }, O" f) k( T9 {其中__STATIC_INLINE,就是静态、内联:/ H+ H* k% D- N. L1 S2 u0 B
- ) h+ _7 D( q+ [% R% w# t% y
- #define __STATIC_INLINE static __inline
复制代码 3 x, `, U# s1 g1 X
而读写位的定义:
- [; E/ Z4 c7 o+ t3 Q- `3 O6 o8 u
8 o) n. F" s4 y& d- Z这里面的红定义,在众多外设.h中都在调用。比如使能USART:
" P3 |/ _* S. {2 ]" o, o' T7 M) ~5 F* p, |5 q& ` }
. s9 R+ v/ X- U% m$ d2 D
LL使能USART:
) Z ~4 D( j4 q! v( ]( X% z: ~- 4 o! U: m" N$ o( }
- __STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx)
# ^( m3 P" N' r( N1 M& u2 Y9 j+ u - {
3 S9 |" D6 q" }$ I& ~ - SET_BIT(USARTx->CR1, USART_CR1_UE);. N" d! L# @, U& r
- }
复制代码
+ s. I1 a4 P" J* P3 ]0 u, `6 b标准外设库使能USART:
( U) t4 S7 H w$ f' J
7 `! m! Q; P H1 Q7 c+ s- void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
) t! ]% Y8 h1 Z - {
; d1 l6 F- o% u& w3 x - /* Check the parameters */- l& Y% ^, c+ I6 M1 g
- assert_param(IS_USART_ALL_PERIPH(USARTx));2 T% J1 }, O4 b1 _3 Q- q
- assert_param(IS_FUNCTIONAL_STATE(NewState));# `& `# }# O- s& @
- ' h$ ~/ R/ l- F: j4 \
- if (NewState != DISABLE)- t% o5 Z1 C$ I) s( g9 n9 M
- {
6 T7 z4 f2 Q' X% y2 Z9 }% c - /* Enable the selected USART by setting the UE bit in the CR1 register */
& [% W) t+ }% X$ y' B, m% p+ ~ - USARTx->CR1 |= USART_CR1_UE;
4 Z b( }! R$ Y; t - }0 N) m3 F% W4 Z- f1 z/ ]0 F
- else
* p' _4 D; i7 e' R" I' k* k - {$ z1 d* O2 @9 I" O
- /* Disable the selected USART by clearing the UE bit in the CR1 register */1 E( F* M7 }* R+ I T( ^
- USARTx->CR1 &= (uint16_t)~((uint16_t)USART_CR1_UE);
: ?4 z+ ]2 T: o( W - }8 z% A+ t7 F' a, D4 W- J
- }
复制代码
' Y* T+ e0 {9 Z! ?: E- |5 B2 K你会明显发现:LL库的执行效率更高。# g* w! N* {0 e4 {0 L2 e! O: q
' I3 |. F: K/ l8 T# T& w% D! e3 P" I# n* u4 F
1 E/ P$ c1 {& o9 L' K2 E+ n
3拓展:内联函数
* B. w4 A, S. U0 a1 y: c# Y( M6 V写到这里,就顺便复习一下内联函数。
8 U& r5 ~' E8 _5 P* c
6 T& X- B( A1 @- d% G1 L% L- F* \内联函数是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展。- |! {* @$ k- S9 i+ U; N
---来自百度百科
& s9 W! ~, d9 e7 x% ?/ ~5 n) k) R- v' W9 @
通常,程序执行时,处理器从内存中读取代码执行。当程序中调用一个函数时,程序跳到存储器中保存函数的位置,开始读取代码执行,执行完后再返回。
' d$ f/ p r3 ?% L" r" B( C3 e; B3 F( f7 {: p
为了提高速度,C语言定义了inline函数,告诉编译器把函数代码在编译时直接拷贝到程序中,这样就不用执行时另外读取函数代码。5 `& K6 ?5 ^, z# H/ c# Q
. T% R" h4 X9 ~
提示:1 ]/ D; l$ x7 q: n
9 V1 C' A7 O0 B( H' ] b& j O7 I9 Y1 E p2 b3 E
当内联函数很大时,会有相反的作用,因此一般比较小的函数才使用内联函数。
4 X! {( Y6 x% [' G
4 K( ]* ` t0 f& e7 D5 S4拓展:软件框架思维1 c7 f, b% ]3 G" n. y2 Q, ~
LL之所以高效,是因为它巧妙运用了一些C语言知识,没有太多封装,直接或间接对寄存器进行操作。' N8 N9 Z) E* T; J2 ]- k
' q. O( D" ], b# C4 y' N2 ]& R# x
而能这样实现,归功于ST开发团队设计了这么一个中间层软件框架。- |" A$ i7 C! g7 F: M
8 Q+ i# S/ L& z) G% E" x* ^- S9 ?
对于有大型项目开发经验的人来说,一个项目的框架对整个项目影响很大。
. @9 E' l. T( C. y, [) \- L+ Q c x z( F' e$ C# Q! C7 m2 b
就好比你建一栋楼,如果楼层框架都没造好,你觉得这栋楼质量会好吗?
5 {1 s0 V* c* k
$ T% f% w$ H0 f7 c所以,这里就提到,我们编程时,特别项目较大,需要考虑一下软件框架,一个好的框架能让你你的项目达到事半功倍的效果。3 v) R0 J7 N0 R9 K8 _8 Y4 c8 O
: U& j: |* S; Q. Y, |
7 p/ k8 [# u- _3 C/ }) B$ `, A) p! o' n$ W& F2 G# u. a
7 d. A- D r$ b/ X0 S$ B! ?8 i
0 r4 W2 J1 F) J
* f, I4 A; q7 E& _
3 |5 I9 k( I+ s7 S, ?( _
$ w3 C2 B- ~6 A% ~1 u- X
; T5 g# [: ?7 S. v) Q( p |