你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】如何生成库文件(MDK 和 IAR)

[复制链接]
STMCU小助手 发布时间:2022-3-1 12:28
问题:2 k0 R: A8 C+ s; f
该问题由某客户提出,主要是想自己做一个库给第三方,但是又不想让别人得到源代码,不知道如何去做,尝试了几种办法,发现都会有些问题.
/ p2 K3 A/ {" H* P" S/ X! V0 ~- b8 d, ?, O+ I- y0 i
调研:% E( B4 _: W8 S0 F
目前 ST 已经提供了各种开源的库文件(如 USB/Ethernet 等等),但是部分客户依然有使用 IDE 生成可加密的库文件的需求,因各种 IDE 之间在生成库的方法上有些不同,调用的方式也有细微的差别,所以大部分工程师还是需要有一个初级入门的文档供来参考。
4 }( B# g' ^2 w1 }' {6 \! `6 Y0 G& z' U+ z
/ g* ^* `: v) m
结论:
7 d- `6 L+ R9 L( _- u0 S撰写了一个小的说明文档发给客户,按照 demo 程序生成自己的库文件。4 ?  O, @* P7 n* u
) @9 k2 W0 E" P) A4 J7 O

4 @$ e1 \" A4 n; S+ w  S处理:: Q' [6 A6 H8 q& p4 M2 G. E
1.适用范围
% e7 _( W. f# O5 R) e5 w本文基于 STM32F40xDiscovery 做的测试,MCU 为:STM32F407VGT6 和 STM32F4101VCT6。关于其他 ARM 未做相关测试。但基本原理是相同的。* y" k7 M2 I$ f" n
2.思路概述
2 J- |! f( ?7 S2 Z' d. W该文主要是讲解了在 Keil 和 IAR 环境中实现库文件的生成。并且如何使用已经生成的库函数。我们正常提供给别人的只有一个‘*.h’和‘*.lib’或‘*.a’,这样可以既实现了代码的加密(不可更改),又会给别人一个方便调用的库函数.; \. X. j0 q% M- ~, [1 E0 u7 B
3.开发环境
7 ?& E& m; _; W5 ?8 u( eIAR:V6.60; O% A6 O2 R' p1 R1 Z) d. z

! M; w+ P; i& I- ]8 q2 Y& H& n WOM$((0{S[`ADGZ6X1P.png
+ \' @6 \! e; l, R
7 J0 X8 P1 h% d
  1. Keil:V5.0
复制代码
) C9 J! @. f8 B4 @
{INPP){9JI{INP7{(GOV4$H.png
0 |; ]  M1 S2 z2 p0 L( d
' @; K! o! @8 b% j' Z- @4 x# A硬件:STM32F4DISCOVERY 和 STM32F401C-DISCO
8 a  {& k2 t* h) i' }& T& C  z4.技术实现
- f+ y+ d; a4 [5 Z: k. o0 ?在此以生成库的方式来实现亮 LED 为例。这里我们先编写两个文件,LED.c 和 LED.h.LED.h 文件内容:* m) w/ N& m0 B3 s! e. H2 o
3 |4 Q. |: U0 [- H" B. c
7 Q( w+ m! n. x
  1. /*----------------------------------------------------------------------------
    & ~' q" M. D9 o+ d
  2. * Name: LED.c
    9 ?7 A9 O  v4 E! G$ G
  3. * Purpose: low level LED functions. `- b5 r% c8 Z6 K* g
  4. * Note(s):
    # M1 Z1 d7 R; {( v
  5. *-----------------------------------------------------------------------------*/+ p! c7 A" s6 T0 I
  6. #include "STM32F4xx.h"
    - E. t6 @5 e. E4 X9 ]* o" p
  7. #include "LED.h"
    ' b6 D& j/ {; F$ ~% E( ^
  8. const unsigned long led_mask[] = {1UL << 12, 1UL << 13, 1UL << 14, 1UL << 15};4 X( \( x0 B0 _# v0 h/ m% I
  9. /*----------------------------------------------------------------------------
    ( l; r+ U/ P& z3 F' k3 Q
  10. initialize LED Pins! F5 `6 }. Z3 |
  11. *----------------------------------------------------------------------------*/, P) h3 l' P9 M: `! y% I/ h6 u
  12. void LED_Init (void) {
    ! @* F) D  T# v* v/ |5 |
  13. RCC->AHB1ENR |= ((1UL << 3) ); /* Enable GPIOD clock */
    ! T4 r; U$ U3 _; k# \
  14. GPIOD->MODER &= ~((3UL << 2*12) |' J8 ]" _, r1 V% S
  15. (3UL << 2*13) |  }5 v, L& L, s4 {3 k* K. T0 M
  16. (3UL << 2*14) |
    + I7 e9 a" a8 U. _% Y4 ?+ h
  17. (3UL << 2*15) ); /* PD.12..15 is output */
    : l. {# m  l) c; v# w9 s& D- X
  18. GPIOD->MODER |= ((1UL << 2*12) |; _& z* ]+ p$ r9 v8 W7 P% B( e
  19. (1UL << 2*13) |7 V; Z! z$ i' Y
  20. (1UL << 2*14) |
    6 j  ^+ A) ?( O* r, }
  21. (1UL << 2*15) );
    & m+ `+ a/ e5 K+ C/ G
  22. GPIOD->OTYPER &= ~((1UL << 12) |1 g: Q) G. h9 I  E% H
  23. (1UL << 13) |3 M( d  \/ S* t) Z( j! C
  24. (1UL << 14) |
    % W/ I7 i/ ]. r7 `" Q+ z
  25. (1UL << 15) ); /* PD.12..15 is output Push-Pull */* q/ z7 o# s- B2 k5 C; W
  26. GPIOD->OSPEEDR &= ~((3UL << 2*12) |
    # _* d4 E; _/ K5 N" A2 ~
  27. (3UL << 2*13) |
    5 @& e4 a: \6 {" i
  28. (3UL << 2*14) |  X4 |1 T  r0 C3 r! t
  29. (3UL << 2*15) ); /* PD.12..15 is 50MHz Fast Speed */4 `, n! l* e. t# U6 B8 t4 N0 g
  30. GPIOD->OSPEEDR |= ((2UL << 2*12) |# t/ O, c5 Q& f2 \9 P' b
  31. (2UL << 2*13) |* F. N0 w6 y/ w; h5 Q3 v  ]
  32. (2UL << 2*14) |4 Z. d; p! R* {, K+ E  g4 z
  33. (2UL << 2*15) );# e  q4 W/ A# v
  34. GPIOD->PUPDR &= ~((3UL << 2*12) |$ Z/ K2 r1 b6 a' x: k- z/ [
  35. (3UL << 2*13) |
    5 P% K' T4 Q3 I" O
  36. (3UL << 2*14) |. B' h5 j, w4 I/ w9 s
  37. (3UL << 2*15) ); /* PD.12..15 is Pull up */
    $ G5 h1 K; W7 `" Z; |  q
  38. GPIOD->PUPDR |= ((1UL << 2*12) |
    * I$ h% m" I  T
  39. (1UL << 2*13) |
    % z$ T' F7 R6 u9 j' d
  40. (1UL << 2*14) |
    - H1 }+ \  H& c) E
  41. (1UL << 2*15) );
    ) \' R7 Z8 n- |
  42. }
    " [( H' L1 f; j3 b4 q
  43. /*----------------------------------------------------------------------------& Q4 z4 h; }8 X( ]
  44. Function that turns on requested LED% i: i8 |0 Z6 [( @& f. b7 w& c
  45. *----------------------------------------------------------------------------*/4 D& j1 d% ^1 K4 t6 ]
  46. void LED_On (unsigned int num) {
    # ~4 W( c/ [: D' N8 t
  47. if (num < LED_NUM) {
    8 k# c+ V+ w- M1 I
  48. GPIOD->BSRRL = led_mask[num];
    % ?& G& ?# p+ ~, B6 r
  49. }
    ' l4 q4 ~; o# P4 c
  50. }, W% ~1 |/ d$ E2 h) Z
  51. /*----------------------------------------------------------------------------
    % `+ }$ K% u# i8 ]) G- z8 v, f+ ^( ?
  52. Function that turns off requested LED
    * a( I: `, n/ |. H! A$ K
  53. *----------------------------------------------------------------------------*/
    0 }1 O( @0 h2 c/ @, b% f0 v1 D0 v
  54. void LED_Off (unsigned int num) {
    7 A2 k5 p; L- C. |+ M
  55. if (num < LED_NUM) {' L5 F; O7 }4 ?9 F) @. i
  56. GPIOD->BSRRH = led_mask[num];
    3 w/ u9 Q* |9 q
  57. }$ Q4 x1 A: M: i/ K8 K
  58. }- g' C6 R/ \, A- c$ r+ E/ U
  59. /*----------------------------------------------------------------------------0 r0 @, K" X8 e" R' Y' f! H$ P1 P
  60. Function that outputs value to LEDs
    ' t2 T% R+ q9 y0 U
  61. *----------------------------------------------------------------------------*/6 Z+ p  b0 f* @2 Z9 \
  62. void LED_Out(unsigned int value) {
    $ X6 E( w# h# _% t1 T
  63. int i;2 z, k' a( V6 c  h' u7 s& F  `
  64. for (i = 0; i < LED_NUM; i++) {5 d, O# F/ d& c5 @
  65. if (value & (1<<i)) {
    - N6 e( \3 ?7 j7 }3 I
  66. LED_On (i);! q( i, h) }0 m" q& u4 Q0 O
  67. } else {
    ; `5 c& z; p; ?3 [/ r1 R9 Y
  68. LED_Off(i);
    ' o( b' P7 R. N6 t0 \
  69. }9 V/ l# o, ]0 D; k! w4 g
  70. }
    $ s% F7 G0 P- e8 F; D& {8 K' Q8 `
  71. }
复制代码
LED.h 文件内容:! B) I1 j/ A% Y  G4 p- Z
  1. /*----------------------------------------------------------------------------; ?9 F. s  W1 [$ E
  2. * Name: LED.h: J* o# Y$ f  B) T
  3. * Purpose: low level LED definitions! O5 r. a  F& J- X  d# F
  4. * Note(s):
    $ F) k$ g6 t3 t1 W8 \; `
  5. *----------------------------------------------------------------------------1 ?( c8 }# D, A( Y- U9 D
  6. * This file is part of the uVision/ARM development tools.
    - e/ K0 m8 h0 d" U: V, R
  7. * This software may only be used under the terms of a valid, current,2 i$ R3 `( J; G" c
  8. * end user licence from KEIL for a compatible version of KEIL software8 U. }* m+ W* K) Y0 q
  9. * development tools. Nothing else gives you the right to use this software.
    " j* s+ ]! _) b) b) p2 J8 n  D
  10. *( X: P2 x6 b, s/ ]
  11. * This software is supplied "AS IS" without warranties of any kind.4 U1 q8 c0 ?  K# Y* E" N" y: H
  12. *
    1 c/ P3 U& G: V
  13. * Copyright (c) 2011 Keil - An ARM Company. All rights reserved.. I7 u$ E% ^; m+ G
  14. *----------------------------------------------------------------------------*/
    ( ^$ O: l) p( n4 u
  15. #ifndef __LED_H8 q  q3 O3 r8 X( i
  16. #define __LED_H
    * ]1 T0 o. d8 E) c5 w  r5 k3 S
  17. /* LED Definitions */7 y: j. B7 E- c2 o* A
  18. #define LED_NUM 4 /* Number of user LEDs */1 f$ W. |( h7 n; P2 i0 T# R" h' y
  19. extern void LED_Init(void);1 K* f7 U7 O8 l) d/ y6 _
  20. extern void LED_On (unsigned int num);7 ~9 D5 J8 a: F; t7 m4 }1 B
  21. extern void LED_Off (unsigned int num);* |8 j! B3 g$ M9 n* L
  22. extern void LED_Out (unsigned int value);
    3 E$ u' u8 N. l% c  N
  23. #endif
复制代码

4 F6 s. a! @7 b# C- K9 D  z, C& Y
; q" c: d! a6 |* n4.1Keil 环境中库的应用
3 m2 \) f- L# F5 z9 e, q1 i4.1.1 如何生成*.Lib- R2 V6 @& I3 a! n4 d) K0 W
新建一个工程,命名“lib source”,添加“startup_stm32f4xx.s”“LED.c”“system_stm32f4xx.c”三个文件在工程 usr lib 里:
4 Y$ a8 A1 b9 P2 W注:“startup_stm32f4xx.s”和“system_stm32f4xx.c”在 keil 的安装目录中。
6 A0 l- r1 f, Z/ I- f3 Q% |+ R: G  O: a3 s9 L) Y

' K4 H: t' G4 x7 S+ J* I* v Q@8C5LVYZ6J@1)K4IZ3I3RY.png ; N. J. {/ j# ]* B- N

! V: e8 R- |) W- @ Options 里设置“Create Library….”项。
( v6 m. e' |; K" U. u" A. N( Y! K' _6 V5 T3 j3 t6 m3 p) X
$)PX9M%9W3Q9$%4@YDEC.png $ q* n' E8 f4 h0 ?; `, s# y& g
. s% d% N& n' p4 R; R$ S7 u
点击 F7,运行生成 lib source.lib 文件。这时候在工程路径中就会生成 lib source.lib 这个文件。如下图所示。
; ^1 O/ e% p1 m# z0 t5 x& T& x$ O
/ I+ W% k$ L! } 8J()3Q)U143(1ZOOY{[UG)E.png & }/ K2 H6 G' v( z

" `0 X1 B# r" r4 O2 Z/ }2 e4.1.2 如何调用库
4 g  i! d! j* n- Q在新建的工程中添加上我们所需要的 lib source.lib 文件和对应的头文件 LED.h,在自建的主文件 uselib.c 中包含 LED.h 文件.# X. ~6 i; n2 N8 y. z1 L
use lib.c 文件的内容如下:注意:以下 IAR 中的文件也是相同的内容。/ z1 G, U0 r1 r, G4 a+ ?
  1. <div>#include "LED.h"</div><div>int main(void)</div><div>{</div><div>LED_Init();</div><div>LED_On(0x1);</div><div>LED_Off(0x1);</div><div>LED_Out(0x3);</div><div>}</div>
复制代码
9 ]# x# _  ^3 ^6 d7 d" T* l: k
- u3 M& ^- q/ E+ G2 m5 Z  V! j
在工程中添加上“lib source.lib”“system_stm32f4xx.c”“startup_stm32f4xx.c”“文件。如下图所示。3 U2 b4 o( j) j5 W- K: u$ L
8 v7 g9 n' P, a; N
3 C# m. G* l/ u, ?  i6 {
) Y7 r+ I: c' ?* C
这时候我们的就可以正常调试了,试试你的 LED 是不是按照库中所实现的功能来运行了.
! v# C0 H2 H" V. }' b- k# q注意:system_stm32f4xx.c 和 startup_stmewf4xx.s 在上一个工程中可以复制过来,这个部分的内容是相同的.与 MCU 型号和 IDE 有关.: N9 a, e. f& w7 }% A! B3 h3 H  u  n
4.2IAR 环境中库的应用
% |4 |. o6 `' n( F- N& w4.2.1 如何生成 Lib 文件
+ ?4 ^: U/ T1 v& N4 d6 X1 |: U新建工程选择如图:$ ?2 l1 Q8 W6 H7 w: p8 i9 {/ h

: ^& \, x" T& {" G. m %]N`~C%KGX~4S(C4J83GN_R.png 6 J7 y% Q4 Y2 {' q" }' ~( r
: O- p5 j! s$ E) q) n4 K
右键-Option
0 W4 _8 i3 O2 y( F) [) [2 H/ O4 S* y, ~" ]* D  I# C* {
7PW7C6VCN9~6%~87H}BP8$E.png 5 K. g  ^. _# u+ T+ Z' d

5 H0 u$ v) }% k# ^% [6 d: FOutPut 选择输出文件位置
0 k" Q) V4 {3 O% w( d5 x' w5 w) J6 ]  L4 v" `% |+ v
2(45%X`J}%G6(G_@Z4~4_07.png / n" U3 k' g# _' X. d8 [! m
0 x( ~! X9 R" _% H( N7 q
选择 Library 的类型
  M5 s% V! s' ^3 f/ N9 `
( K' r1 p& _% D" N5 B2 I/ A7 ` `QIH{K2G]GG69_TR_{97`01.png
% z6 W. H3 W! Y; q' q  B8 [* i$ T# \/ |+ Y6 o9 ^
选择优化最大
! g6 f5 B' F' M  Z  v, {5 Z, F6 S( r0 ^5 v% n9 u, ]  }
_8XP21)[XPRF)JW~SSL5X0S.png 6 Y6 i- i+ `# x8 _

# |6 L8 S- H/ A1 T. L覆盖旧文件' ?, W* p4 t9 Y+ w
1 y# e, f3 g2 s1 s1 {  P9 e
2_S5}X(KLN2IW~XX)4[4{I6.png / U0 M3 E. G% X: a9 u4 q
$ T0 r. |4 }' ^1 l  |
直接运行生成 lib source.a 文件,如下图所示:
, Q  h# r: c/ `7 z) m0 g* b0 I8 t. R$ h% }2 p5 U3 M
07EB75OW2}J]5Q8`}II333H.png 1 ?. ^4 u6 K' G5 Q& Y' m

' a7 y1 v& {% n! V4.2.2 如何调用 IAR 生成的库文件
) g- k9 ^! v) |. y新建立一个 IAR 工程,将生成的“lib source.a”文件添加到工程中。如下图所示。
8 q; }0 R+ y, e' a  K5 D
6 T% l+ Y: @. f8 a9 M
. D! P2 o) d/ R! `( H
' \& \0 {8 r7 Quse lib.c 文件的内容不变.即可编译调试代码运行情况了.
, A! j5 i2 V$ {! y( w, L% y+ u3 C) [注意:startup_stm32f40xx.s 和 system_stm32f4xx.c 是在 IAR 环境下的文件.use lib.c 与在 Keil 环境下所使用的文件内容是相同的.6 D& C# b8 d$ j% M0 w1 J: ]
3 O" z- }7 V7 H
建议:1 k7 {, N  P& U0 Q5 ~
类似的问题其实是工程师的一个基本技能,以后我们是不是会针对工程师的基本技能出一个常见问题集锦,以便以后的工程师查阅。* p6 l5 ~) B  H* {7 U& C4 k

3 d$ F( P0 x1 j# N) y, v* x$ h4 c2 l) }) P4 ^
8 v2 _$ q; b1 m$ P
# N* R) y' I* h9 E, t- q

! r$ O( s" X8 C8 b, F' E, N+ z: ]; C2 x3 ]; M! x7 w' @) w

, L2 y, E6 U9 A. V" T( A1 e! X& J0 z" k) S) u
; ~4 f$ i" X# w7 v  _) ^6 T# l) T' q  B
% x# _) ]% I+ O1 }

: V: z/ Q  z$ Q. j2 p  Q+ q; q+ V6 X" P2 `
7 i& s: K; G1 [. s. g; j

* _1 |9 {: e$ ^5 A
* G" x$ Y! y! `1 T- R% o
- @: Z( L( L. Z6 e5 B" S' p
5 p% \1 u( H- t4 s* r/ q7 Z
# {8 m3 ^1 I. [* A  Q! I7 }
赞 收藏 评论0 发布时间:2022-3-1 12:28

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版