MDK关于microlib库问题笔记

关于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,调试的过程中会出现莫名的死机,并无法直接跳转到主程序,尝试寻找从那里引入的这个问题,具体过程如下:

  1. 移植UCOSIII之后的程序,添加以上修改后不选中microlib库没有出现编译错误提示;
  2. 移植UCOSIII+LWIP之后的程序,添加以上修改后不选中microlib库出现编译错误提示;通过查找是LWIP调用printf函数引起。经过仔细查找发现屏蔽这里的时候不再报错;

#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \

  printf("Assertion \"%s\" failed at line %d in %s\n", message, \

__LINE__, __FILE__); fflush(NULL);handler;} } while(0)

这里可能的原因是由于调用了fflush(NULL);但是虽然暂时把这个函数去掉,但是如果不勾选microlib库,系统仿真就无法运行,一直出现硬件错误。

        3. 可以看出虽然暂时解决了不勾选microlib库所引起的编译错误,但是无法解决调试出现的硬件错误问题,应该还是关于microlib库那里有调用引起的,可能是mallco函数,暂时猜测是这样的。

这里并没有解决microlib库未勾选时引起的硬件错误问题,在后面调试过程中可以对这个问题进行分析。

posted @ 2017-07-12 14:44  thinkwhat  阅读(5784)  评论(0编辑  收藏  举报