keil lib 只调用自己的函数_keil中生成个人库文件及调用方法

本文介绍在Keil环境下如何创建并有效使用自定义的LIB库,包括解决未调用函数的编译警告,以及将LIB文件添加到工程的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

--------

下面是我用库的

一些记录

--------------------------------------------------------------------

库的生成

<think>我们正在处理一个嵌入式系统开发中的问题,具体是关于Keil MDK环境下使用库文件lib)时出现的SysTick_Handler未识别问题。根据用户提供的引用信息和问题描述,我们可以分析如下: 关键点: 1. 用户生成了一个lib库,其中包含了SysTick_Handler的定义(可能是重写了该中断服务函数)。 2. 在原工程中使用该lib库时,链接器报告SysTick_Handler未定义(或者重复定义)的错误。 分析: 在STM32的标准启动文件(startup_stm32fxxxx.s)中,已经定义了弱(WEAK)符号的SysTick_Handler。如果用户在自己的代码(例如main.c)或者库中提供了SysTick_Handler的强定义,那么链接器会使用强定义覆盖弱定义。 但是,当用户将代码编译成lib库时,如果原工程中已经包含了启动文件(其中包含弱定义的SysTick_Handler),而lib库中也包含了SysTick_Handler的强定义,那么理论上链接器应该选择lib库中的强定义。然而,问题可能出现在以下几个方面: a) 原工程中已经存在一个强定义的SysTick_Handler(例如在main.c中),导致lib库中的定义被视为重复定义。 b) 原工程没有正确链接lib库,或者lib库中的符号没有被正确提取。 c) 原工程中使用的启动文件可能没有将SysTick_Handler标记为弱定义(WEAK),导致链接时出现重复定义错误。 根据引用[5]:“keil5使用lib尝试。原因是缺少了启动文件,startup_xxx.s,只需要把该文件添加到项目下即可”。但这里用户的情况是原工程已经有启动文件,所以问题可能不是缺少启动文件,而是启动文件中的弱定义和lib库中的强定义冲突。 解决方案: 1. **确保原工程中只有一个强定义的SysTick_Handler**:如果原工程中(例如main.c)已经定义了SysTick_Handler,那么需要移除该定义,因为lib库中已经提供了。或者,如果lib库中的SysTick_Handler是希望被使用的,那么原工程中不应该再定义。 2. **检查启动文件中的定义是否为弱定义**:在启动文件中,应该看到类似下面的代码: EXPORT SysTick_Handler [WEAK] 这样,如果其他地方(如lib库)提供了强定义,链接器就会使用强定义而不会报错。如果没有[WEAK]属性,则会导致重复定义错误。 3. **检查lib库是否被正确链接**:在Keil工程中,需要将生成lib文件添加到工程,并且在链接器设置中指定库的路径。同时,确保lib库的编译选项(如目标处理器、FPU等)与原工程一致。 4. **如果lib库中的SysTick_Handler需要覆盖启动文件中的弱定义,确保链接顺序正确**:通常,链接器在链接时,先链接obj文件,再链接库。如果启动文件中的弱定义在obj文件中,而lib库中的强定义在库中,那么链接器在遇到启动文件中的弱定义时,会先使用它,然后在链接库时发现强定义,可能会报重复定义。为了避免这种情况,可以尝试将lib库放在启动文件之前链接?但是Keil的链接顺序一般是固定的。另一种方法是,将启动文件中的弱定义保留,而lib库中的强定义会被优先使用(因为强定义优先级高于弱定义)。所以,只要确保lib库中的定义是强定义(没有用WEAK修饰),那么链接器会自动选择强定义。 5. **如果问题仍然存在,可以尝试在启动文件中注释掉SysTick_Handler的弱定义**:但这种方法不推荐,因为启动文件是标准文件,修改后可能影响其他中断。 6. **另一种方法:将启动文件中关于SysTick_Handler的弱定义删除,然后只在lib库中提供定义**。但是这样修改启动文件会使得工程维护困难,特别是当更换芯片型号时。 7. **检查是否在lib库中正确定义了SysTick_Handler**:确保在lib库的源文件中,SysTick_Handler被正确定义为一个全局函数,并且没有static修饰,这样它才能在链接时被其他模块看到。 8. **检查函数名是否完全一致**:注意拼写和大小写,SysTick_Handler必须完全一致。 根据引用[4]中的启动文件代码片段,我们可以看到SysTick_Handler被定义为弱符号: SysTick_Handler PROC EXPORT SysTick_Handler [WEAK] B . ENDP 因此,正常情况下,只要用户在自己的代码或库中提供了强定义的SysTick_Handler,就会覆盖这个弱定义。 所以,问题很可能是在原工程中已经有一个强定义的SysTick_Handler(比如在main.c中定义了一次),而lib库中又定义了一次,导致重复定义。或者,lib库没有被正确链接,导致原工程中启动文件的弱定义没有被覆盖,而用户又在其他地方调用了SysTick_Handler(但lib库没有链接进来),导致未定义错误。 具体步骤: 情况1:重复定义错误 - 检查原工程中是否有多个地方定义了SysTick_Handler(例如在多个.c文件中,或者在启动文件和lib库中都有强定义)。如果是,则保留一个(建议保留lib库中的定义,并删除原工程中其他定义)。 情况2:未定义错误(可能是lib库没有链接进来) - 检查Keil工程设置中是否添加了lib库文件(.lib)到工程中。 - 检查Keil的链接器选项,确保库搜索路径设置正确。 - 确保lib库的编译选项与原工程一致,特别是处理器型号和浮点单元设置。 情况3:函数名不一致 - 检查lib库中定义的中断函数名是否与启动文件中声明的完全一致(包括下划线和大写字母)。 总结解决方案: 1. 移除原工程中(除了启动文件外)所有对SysTick_Handler的定义。 2. 确保lib库被正确添加到工程,并且链接器能够找到它。 3. 如果启动文件中没有将SysTick_Handler标记为弱定义,则需要更换标准启动文件(或添加[WEAK]属性)。 4. 如果lib库中的SysTick_Handler没有被使用(即启动文件的弱定义仍然被使用),可以尝试在lib库中定义时使用更强的链接属性(例如不使用static,且定义为全局函数),并确保lib库在链接时被包含。 另外,引用[5]提到,建立工程时一定要添加启动文件,并且注意选择对应容量。所以请确保原工程中包含了正确的启动文件。 如果以上步骤无法解决,可能需要检查lib库的生成过程,确保生成lib库时没有排除包含SysTick_Handler的源文件。 最后,建议用户检查错误信息是“未定义”还是“重复定义”,这有助于定位问题。 由于问题描述中没有给出具体的错误信息,以上分析基于常见情况。 相关问题: 1. 如何在Keil中正确添加和使用自定义的库文件(.lib)? 2. 如何解决嵌入式系统中的中断服务函数重复定义问题? 3. 在STM32开发中,如何覆盖启动文件中定义的弱符号中断服务函数? 4. Keil链接器在处理库文件和用户代码时的顺序是怎样的? 5. 如何生成一个包含中断服务函数Keil库文件(.lib)?</think>### Keil生成lib库包含SysTick_Handler,但原工程无法识别的解决方案 此问题通常由**启动文件冲突**或**链接顺序错误**导致。以下是具体解决步骤: #### 1. **检查启动文件中的弱符号定义** 在标准启动文件(如`startup_stm32fxxx.s`)中,`SysTick_Handler`被定义为弱符号(`[WEAK]`): ```assembly SysTick_Handler PROC EXPORT SysTick_Handler [WEAK] ; 关键弱符号声明 B . ENDP ``` **解决方法**: - 确保原工程使用的启动文件包含`[WEAK]`属性,否则lib库中的强定义会引发冲突[^2][^4]。 #### 2. **验证lib库的链接顺序** Keil链接器按**文件添加顺序**解析符号。若启动文件在lib库之后链接,弱符号可能覆盖lib的强定义。 **解决方法**: - 在Keil工程中,将lib库文件拖到启动文件(`.s`)的上方(优先级更高): ``` 工程结构示例: ├── MyLib.lib # 需在启动文件上方 └── Startup/startup_stm32f4xx.s ``` #### 3. **排查重复定义** - **场景1**:原工程有其他文件(如`main.c`)定义了`SysTick_Handler` → 删除原工程中的额外定义,仅保留lib库的实现。 - **场景2**:lib库编译时未正确导出符号 → 在lib库的源文件中添加`__attribute__((used))`确保符号不被优化: ```c void __attribute__((used)) SysTick_Handler(void) { // 中断处理代码 } ``` #### 4. **检查启动文件兼容性** 确保启动文件与芯片型号匹配(如`startup_stm32f407xx.s`对应F407)。错误的文件会导致中断向量表偏移[^5]。 **操作步骤**: - 在Keil中右键点击启动文件 → Options → 确认芯片型号正确。 #### 5. **验证lib生成设置** 生成lib库时需启用**中断向量表**支持: - 在lib工程中,勾选`Options for Target → Output → Create Library`,并添加启动文件到lib工程[^3][^5]。 --- ### 相关问题 1. **如何解决Keil中多个中断处理函数的重复定义错误?** 2. **在STM32工程中,弱符号(`[WEAK]`)的作用是什么?** 3. **Keil链接器处理库文件和启动文件的优先级规则是怎样的?** 4. **生成Keil库文件时,如何确保中断向量表被正确包含?** 5. **STM32启动文件中`B .`指令的作用是什么?** [^1]: 内核中断处理函数需在启动文件中声明弱符号 [^2]: 启动文件通过`[WEAK]`允许用户覆盖默认中断处理函数 [^3]: HAL库工程需正确配置启动文件和链接顺序 [^4]: `Reset_Handler`调用`SystemInit`后跳转到`main`,中断函数由弱符号预留 [^5]: 缺少启动文件或型号不匹配会导致中断向量表错误
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值