本帖最后由 seawind1986 于 2017-4-7 22:30 编辑
第一步用Stm32CubeMX创建一个工程并生成Keil MDK的工程,不多赘述。
第二步将标准库的FWlib文件夹整个拷贝到刚才Stm32CubeMX生成的的工程路径下。
第三步将标准库USER文件夹中的stm32f10x_conf.h文件拷贝工程路径下的FWlib\inc下。
这只是为了方便管理标准库的头文件,其实你放到别的地方也可以,只要别忘把路径包含进来就行。
第四步 打开刚才生成的MDK工程,添加个Group 改名为FWLib,并将FWlib\src路径下的所有.c文件都包含进来。
第五步 添加宏USE_STDPERIPH_DRIVER,和标准库的头文件的路径。
这时候貌似已经移植完标准库的库函数了,但是是这样吗?我们点一下编译试试。
这时候会报一个错: Error: L6200E: SymbolFLASH_WaitForLastOperation multiply defined (by stm32f1xx_hal_flash.o andstm32f10x_flash.o). 这是因为hal库和标准库的Flash库里面有个重名函数。因此需要修改其中一个函数的名称。 hal库原则上不要进行任何改名,因为一旦重新使用Stm32CubeMX重新配置工程,Cube将会复原被修改的hal库。 对于这个hal库工程,标准库的文件相当于用户文件,Cube不会对其做任何修改。所以就拿标准库的函数开刀吧。
第六步 替换标准库中重名函数,我的重命名技巧是用替换命令Find栏填上旧函数名加半个括号“(”,Replace栏填旧函数名+“_FW(”。 这样相当于找指定的字符串后在中间插入几个字符串,这样即使你误按了几次Replace也不至于替换错。 需要替换的是标准库的Flash的c文件和h文件,当然如果你其他地方也用到了这个函数那也要替换掉它(请确保是引用的标准库的而不是hal库的,别杀错了) 替换完成以后,再点编译,OK通过了。 似乎我们已经成功了,接下来又是一盆凉水泼下来。
我们要想在c文件中引用标准库的函数,那么就必须将标准库的顶级头文件stm32f10x.h引用进来。
可是我们将它与hal库的顶级头文件stm32f1xx_hal.h同时放到main.c文件中发现有提示错误的下滑波浪线。
肯定是又错了,当然如果你不信也可以点编译试试,会报一大堆错误,这里也就不啰嗦了。
究其原因好像是两个库定义了不少重名的宏。修改这些重名的宏的工作量比较大,如果你愿意一个一个改,我挺佩服你的。
如果不改呢,那么标准库和hal库楚河汉界划分的太清楚了,怎么办?
第七步 创建中间桥梁,我们创建一个Bridge.c和Bridge.h文件
Bridge.h文件中#include <stdint.h>,这个头文件主要是定义了一下数据类型,比如uint16_t之类的常用变量。
不包含它的话你声明函数的时候很不方便。
Bridge.c文件包含标准库的顶级头文件。
第八步 在main.c等需要调用标准库的c文件中包含Bridge.h文件
再点重新编译,发现编译通过, - 0 Error(s), 0 Warning(s).
恭喜你已经将两个库合并成功了。
下面举个例子:
我们在Bridge.c里面创建一个Fun_TestFWLib()的函数,函数的内容我们简单操作一下PA0引脚
并在Bridge.h中声明这个函数。
在main.c文件中定义一个全局变量Counter
在main函数的主循环里面插入如下代码:
HAL_Delay()函数是hal库的函数,而Fun_TestFWLib()函数内部是调用的标准库。
点重新编译 - 0 Error(s), 0 Warning(s).可以仿真一下试试了。
如果有些时候hal库需要调用的标准库函数的形参类型是hal库中所不存在的,那么你可以在Bridge.h中重新定义一遍这个数据类型。因为这个Bridge.h文件不被标准库引用,所以不会报重复定义的错误。
本人现在出差中……
由于手头没有开发板,所以没法进行硬件仿真,软件仿真测试通过。
如果硬仿无法通过还请不要扔砖头。
|