• 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 ", message,

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

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

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

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

  • 相关阅读:
    jenkins+robot_framework的安装与邮件配置
    kali最新版中文乱码破解
    Kali系统安装详细步骤
    ADK安装步骤
    Newman跑接口脚本
    Android手机APP测试之环境搭建
    pytest+allre框架搭建
    Android手机测试环境搭建
    adb电脑桥梁手机步骤以及操作
    Android SDK的安装与环境变量配置
  • 原文地址:https://www.cnblogs.com/longbiao831/p/7155380.html
Copyright © 2020-2023  润新知