Keil中如何使用自己生成的LIB库
代码积累多了,大家可能都尝试过自己写个库,方便调用,我最初的办法是把常用的函数放到一个个.C文件里头,要用的时候就把一个个.C添加到Group里面,这种方法就很麻烦了,每次新建一个工程都要ADD半天
这里8279.C,delay_ms.c,watchdog.c,function.c都是我以前写过现在拿来重用的代码
这样做还有一个问题,如果某个函数未调用,编译器就会给一个警告,UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS,”未调用的段,被忽略”,虽然无啥大碍,但看着也挺不爽的
于是自己生成LIB文件,.lib是生成了,但就是没能用,始终有警告
* WARNING L1: UNRESOLVED EXTERNAL SYMBOL未解析的外部标号
* WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL引用外部为解析的段
因为编译器没有找到那个函数的代码,也就未解析了,百度了一下,前几个结果竟然都没给出一个有效的解决办法
其实问题很简单,你在Group上右键ADD时注意一下对话框中允许添加的文件扩展名,除了c,asm之外,还有lib,把你的lib文件加进去,ok了
——–下面是我用库的 一些记录——————————————————————–
库的生成
库的使用(在group中添加lib文件),在主调的C文件中include .h文件
KEIL中库可以由多个.obj(与.C对应)组成,而连接是以.obj为最小单元,即某.obj中有函数被调
用时,则整个.obj中所有函数都会被连接到.hex文件
通常为每一个函数编一个.C文件,而整个lib用一个.h文件,这样就可以使只有被调用的函数参与连接
Keil 生成Lib 调用Lib
2011-06-01 16:01:49| 分类: STM32学习 | 标签:lib keil 文件 调用 函数 |字号大中小 订阅
1、维护自己写的代码不被别人乱改动。lib 不是c 代码,不能对它编辑,只能通过.h 文
件调用。所以为了别人能使用你的lib,一定要给他.h 文件。
2、可以把多个.c 文件合成一个lib 文件,这样在工程就不必要把每一个.c 文件都添加一
遍。
3、相比添加.c 文件,它具有不使用已经申明的extern 函数也不会出现Keil 经典的
UNCALLED FUNC warning。更重要的是,不使用的函数编译时不会产生代码,从而大大减
小.hex 文件。这对小容量的单片机来说是非常可贵的。
废话少说,下面以本人刚写的1602 程序为例一个教大家怎么生成和使用lib 文件。
为了实现上面说的lib 的第三个作用,大家要把独立的子函数用不同的.c 分开写。因为
该.c 文件一旦使用,那么里面的子函数就会全部被编译,这样就不能达到不调用能节省rom
的目的了。下面是写好的程序:
编译成功后,在project》options for target》Output 中,其设置如图。
点击确定之后就会在你的工程文件夹中产生一个1602.lib 的文件。
再在keil 的project workplace 中把lib 文件添加进去,并remove 掉除mian 函数的其他.c
文件,如图。
Keil的lib生成个人总结
1
推荐
1. 生成lib 的工程可以没有main函数,可以只有一个.c文件,一个.c文件中可以只有一个函数
2. 需要在lib工程中建立一个.h文件, 必须用extern声明各全局变量和函数.
3. 调用lib文件的工程中必须包括lib中的.h文件, 也就是lib工程和调用工程都包含同一个.h文件(好像有点废话)
2.Lib的文件要分的细一点,没有调用关系的两个函数不要放到同一个C文件中. 没有调用关系的最好是一个函数单独放在一个.c文件中.这是为了避免在keil中应用程序调用lib库里出现告警. 因为LIB51在链接的时候是按模块来链接的,一个模块就对应一个C文件,假如链接器因为要使用你一个函数fA而引入了A模块,那么A模块中的另外的函数也会被引入,而另外的函数你又没有使用的话,那么就会引发Keil经典的UNCALLED FUNC的warning。
通常为每一个函数编一个.C文件,而整个lib用一个.h文件,这样就可以使只有被调用的函数参与连接
3.调用lib库时需要在工程中将.lib文件加进来. 在Group中右键,然后Add ,注意文件类型中选择*.lib.
暂时就总结到这里,很重要哟.
LCD1602.C里面包含LCD1602.H
LCD1602.H的文件格式
设置生成lib文件
Lib文件调用
添加lib文件对话框
添加后的lib文件
呵呵^_^,这样就可以删除LCD1602.C文件了,只留下LCD1602.Lib和LCD1602.H文件就可以咯
Keil的lib库函数的封装
在协同工作中,经常会有模块维护和代码封装的问题。把需要封装的代码打成一个lib无疑是一种很好的方式。
1.创建lib
创建一个lib很容易,只需要创建一个target,然后把需要封装的代码全部加进来,然后再Options of Target中选择Create Library,然后编译,因为是lib所以不需要链接,编译过了,你的lib就创建了。当然了,为了别人可以轻松的使用,请提供头文件支持哦。
2.使用lib
使用lib就更容易了,把lib和头文件加入你的工程,直接调用就是了。lib库会和你工程中其它编译后的obj一起链接,形成最后的目标文件。
3.注意事项
首先,Startup和中断处理程序不要封入LIB,这些程序会在链接的时候产生问题。具体的原因么,有点复杂,应该是中断程序的link机制有所不同的关系吧。
其次,Lib的文件要分的细一点,没有调用关系的两个函数不要放到同一个C文件中,因为LIB51在链接的时候是按模块来链接的,一个模块就对应一个C文件,假如链接器因为要使用你一个函数fA而引入了A模块,那么A模块中的另外的函数也会被引入,而另外的函数你又没有使用的话,那么就会引发Keil经典的UNCALLED FUNC的warning。这个warning在Keil的文档中说的好清楚了,我粘过来吧:
It is common practice during the development process to write but not call
additional functions. While the compiler permits this without error, the
Linker/Locator does not treat this code casually because of the support for data
overlaying, and emits a warning message.
Interrupt functions are never called, they are invoked by the hardware. An
uncalled routine is treated as a potential interrupt routine by the linker. This
means that the function is assigned non-overlayable data space for its local
variables. This quickly exhausts all available data memory (depending upon the
memory model used).
If you unexpectedly run out of memory, be sure to check for linker warnings
relating to uncalled or unused routines. You can use the linker’s IXREF
directive to include a cross reference list in the linker map (.M51) file.
大意就是说,Keil的内存应用模式是指定地址的,也就是要根据调用关系来决定哪块地址可以被复用。对于这种没人调用的函数,Keil会认为是中断处理程序,并不能决定调用关系,所以此类uncalled函数的空间不能和其他的程序共享,也就是说,这函数用多少RAM,你就少多少RAM。那uncall多了会怎么样?—-废话,当然是内存溢出了。
所以,lib的功能可以做的大而全,但是里面的模块一定要分的要多细,有多细,只有这样,你才能像在windows上用CRT一样舒服的使用LIB。