关于MicroLIB的介绍
microlib 是缺省 C 库的备选库。它旨在与需要装入到极少量内存中的深层嵌入式应用程序配合使用,这些应用程序不在操作系统中运行。
microlib 进行了高度优化以使代码变得很小。它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。某些库函数的运行速度也比较慢,例如,memcpy()。
与缺省 C 库之间的差异
microlib 与缺省 C 库之间的主要差异是:
microlib 不符合 ISO C 库标准。 不支持某些 ISO 特性,并且其他特性具有的功能也较少。
microlib 不符合 IEEE 754 二进制浮点算法标准。
microlib 进行了高度优化以使代码变得很小。
无法对区域设置进行配置。 缺省 C 区域设置是唯一可用的区域设置。
不能将 main() 声明为使用参数,并且不能返回内容。
不支持 stdio,但未缓冲的 stdin、stdout 和 stderr 除外。
microlib 对 C99 函数提供有限的支持。
microlib 不支持操作系统函数。
microlib 不支持与位置无关的代码。
microlib 不提供互斥锁来防止非线程安全的代码。
microlib 不支持宽字符或多字节字符串。
与 stdlib 不同,microlib 不支持可选择的单或双区内存模型。 microlib 只提供双区内存模型,即单独的堆栈和堆区。
可以合理地将 microlib 与 --fpmode=std 或 --fpmode=fast 配合使用。
microlib 中的函数负责:
创建一个可在其中执行 C 程序的环境。 这包括:
创建一个堆栈
创建一个堆(如果需要)
初始化程序所用的库的部分组成内容。
调用 main() 以开始执行程序。
要使用 microlib 构建程序,必须使用命令行选项 ??library_type=microlib。根据需要,编译器、汇编程序或链接器可使用此选项处理不同的文件。 将此选项与链接器配合使用时,将覆盖所有其他选项。
官网解释
microlib中是用C写的时候相比,包括ARM编译器工具链的标准C库的基于ARM的嵌入式应用提供了高度优化的库,microlib中提供所需的许多嵌入式系统显著代码大小的优点。
microlib中和标准C库之间的主要区别是:
microlib中是专为深度嵌入式应用。
microlib中被优化使用比使用ARM标准库更少的代码和数据存储器。
microlib中已经设计没有操作系统的工作,但是这并不妨碍它被与任何操作系统或RTOS如Keil RTX一起使用。
microlib中不包含任何文件I/O或宽字符支持。
由于microlib中进行了优化,以尽量减少代码大小,一些功能将会比ARM编译工具提供了标准C库函数更慢执行。
microlib中双方和ARM标准库都包含在Keil MDK-ARM。
以上就是对microlib的一些介绍,microlib库突出特点就是小,用时间换空间,从图中可以看到microlib库比标准库减少了一半的代码占用。
是否选用microlib库对项目有什么影响呢?
之前在用原子的例程时,可以不选用microlib,通过添加以下代码:
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
但是在最新的项目中,同样采样这种方法却提示错误,错误内容如下:
Error: L6200E: Symbol __stdout multiply defined (by stdio_streams.o and bsp_debug_usart.o).
提示在串口文件中存在重定义的情况,重定义的内容就是我之前添加的那段代码?如果我不勾选microlib,调试的过程中会出现莫名的死机,并无法直接跳转到主程序,尝试寻找从那里引入的这个问题,具体过程如下:
- 移植UCOSIII之后的程序,添加以上修改后不选中microlib库没有出现编译错误提示;
- 移植UCOSIII+LWIP之后的程序,添加以上修改后不选中microlib库出现编译错误提示;通过查找是LWIP调用printf函数引起。经过仔细查找发现屏蔽这里的时候不再报错;
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) {
printf("Assertion "%s" failed at line %d in %s ", message,
__LINE__, __FILE__); fflush(NULL);handler;} } while(0)
这里可能的原因是由于调用了fflush(NULL);但是虽然暂时把这个函数去掉,但是如果不勾选microlib库,系统仿真就无法运行,一直出现硬件错误。
3. 可以看出虽然暂时解决了不勾选microlib库所引起的编译错误,但是无法解决调试出现的硬件错误问题,应该还是关于microlib库那里有调用引起的,可能是mallco函数,暂时猜测是这样的。
这里并没有解决microlib库未勾选时引起的硬件错误问题,在后面调试过程中可以对这个问题进行分析。