如何生成库文件 (MDK 和 IAR) 问题 : 该问题由某客户提出, 主要是想自己做一个库给第三方, 但是又不想让别人得到源代码, 不知道如何去做, 尝试了几种办法, 发现都会有些问题. 调研 : 目前 ST 已经提供了各种开源的库文件 ( 如 USB/Ethernet 等等 ), 但是部分客户依然有使用 IDE 生成可加密的库文件的需求, 因各种 IDE 之间在生成库的方法上有些不同, 调用的方式也有细微的差别, 所以大部分工程师还是需要有一个初级入门的文档供来参考 结论 : 撰写了一个小的说明文档发给客户, 按照 demo 程序生成自己的库文件 处理 : 1. 适用范围本文基于 STM32F40xDiscovery 做的测试,MCU 为 :STM32F407VGT6 和 STM32F4101VCT6 关于其他 ARM 未做相关测试 但基本原理是相同的 2. 思路概述该文主要是讲解了在 Keil 和 IAR 环境中实现库文件的生成 并且如何使用已经生成的库函数 我们正常提供给别人的只有一个 *.h 和 *.lib 或 *.a, 这样可以既实现了代码的加密 ( 不可更改 ), 又会给别人一个方便调用的库函数. 3. 开发环境 IAR:V6.60
Keil:V5.0 硬件 :STM32F4DISCOVERY 和 STM32F401C-DISCO 4. 技术实现 在此以生成库的方式来实现亮 LED 为例 这里我们先编写两个文件,LED.c 和 LED.h. LED.h 文件内容 : * Name: LED.c * Purpose: low level LED functions * Note(s): *-----------------------------------------------------------------------------*/ #include "STM32F4xx.h" #include "LED.h" const unsigned long led_mask[] = {1UL << 12, 1UL << 13, 1UL << 14, 1UL << 15; initialize LED Pins *----------------------------------------------------------------------------*/ void LED_Init (void) { RCC->AHB1ENR = ((1UL << 3) ); /* Enable GPIOD clock */ GPIOD->MODER &= ~((3UL << 2*12)
(3UL << 2*13) (3UL << 2*14) (3UL << 2*15) ); /* PD.12..15 is output */ GPIOD->MODER = ((1UL << 2*12) (1UL << 2*13) (1UL << 2*14) (1UL << 2*15) ); GPIOD->OTYPER &= ~((1UL << 12) (1UL << 13) (1UL << 14) (1UL << 15) ); /* PD.12..15 is output Push-Pull */ GPIOD->OSPEEDR &= ~((3UL << 2*12) (3UL << 2*13) (3UL << 2*14) (3UL << 2*15) ); /* PD.12..15 is 50MHz Fast Speed */ GPIOD->OSPEEDR = ((2UL << 2*12) (2UL << 2*13) (2UL << 2*14) (2UL << 2*15) ); GPIOD->PUPDR &= ~((3UL << 2*12) (3UL << 2*13) (3UL << 2*14) (3UL << 2*15) ); /* PD.12..15 is Pull up */ GPIOD->PUPDR = ((1UL << 2*12) (1UL << 2*13) (1UL << 2*14) (1UL << 2*15) ); Function that turns on requested LED *----------------------------------------------------------------------------*/ void LED_On (unsigned int num) { if (num < LED_NUM) { GPIOD->BSRRL = led_mask[num]; Function that turns off requested LED *----------------------------------------------------------------------------*/ void LED_Off (unsigned int num) { if (num < LED_NUM) { GPIOD->BSRRH = led_mask[num]; Function that outputs value to LEDs *----------------------------------------------------------------------------*/ void LED_Out(unsigned int value) { int i; for (i = 0; i < LED_NUM; i++) {
if (value & (1<<i)) { LED_On (i); else { LED_Off(i); LED.h 文件内容 : * Name: LED.h * Purpose: low level LED definitions * Note(s): *---------------------------------------------------------------------------- * This file is part of the uvision/arm development tools. * This software may only be used under the terms of a valid, current, * end user licence from KEIL for a compatible version of KEIL software * development tools. Nothing else gives you the right to use this software. * * This software is supplied "AS IS" without warranties of any kind. * * Copyright (c) 2011 Keil - An ARM Company. All rights reserved. *----------------------------------------------------------------------------*/ #ifndef LED_H #define LED_H /* LED Definitions */ #define LED_NUM 4 /* Number of user LEDs */ extern void LED_Init(void); extern void LED_On (unsigned int num); extern void LED_Off (unsigned int num); extern void LED_Out (unsigned int value); #endif 4.1Keil 环境中库的应用 4.1.1 如何生成 *.Lib 新建一个工程, 命名 lib source, 添加 startup_stm32f4xx.s LED.c system_stm32f4xx.c 三个文件在工程 usr lib 里 : 注 : startup_stm32f4xx.s 和 system_stm32f4xx.c 在 keil 的安装目录中
在 Options 里设置 Create Library. 项 点击 F7, 运行生成 lib source.lib 文件 这时候在工程路径中就会生成 lib source.lib 这个文件 如下图 所示
4.1.2 如何调用库 在新建的工程中添加上我们所需要的 lib source.lib 文件和对应的头文件 LED.h, 在自建的主文件 use lib.c 中包含 LED.h 文件. use lib.c 文件的内容如下 : 注意 : 以下 IAR 中的文件也是相同的内容 #include "LED.h" int main(void) { LED_Init(); LED_On(0x1); LED_Off(0x1); LED_Out(0x3); 在工程中添加上 lib source.lib system_stm32f4xx.c startup_stm32f4xx.c 文件 如下图所 示 这时候我们的就可以正常调试了, 试试你的 LED 是不是按照库中所实现的功能来运行了.
注意 :system_stm32f4xx.c 和 startup_stmewf4xx.s 在上一个工程中可以复制过来, 这个部分的内容是相同的. 与 MCU 型号和 IDE 有关. 4.2IAR 环境中库的应用 4.2.1 如何生成 Lib 文件新建工程选择如图 : 右键 -Option OutPut 选择输出文件位置
选择 Library 的类型 选择优化最大
覆盖旧文件 直接运行生成 lib source.a 文件, 如下图所示 :
4.2.2 如何调用 IAR 生成的库文件 新建立一个 IAR 工程, 将生成的 lib source.a 文件添加到工程中 如下图所示 use lib.c 文件的内容不变. 即可编译调试代码运行情况了. 注意 :startup_stm32f40xx.s 和 system_stm32f4xx.c 是在 IAR 环境下的文件.use lib.c 与在 Keil 环 境下所使用的文件内容是相同的. 建议 : 类似的问题其实是工程师的一个基本技能, 以后我们是不是会针对工程师的基本技能出一个常见问题 集锦, 以便以后的工程师查阅