STM32笔记

整理有道云笔记中,关于STM32的笔记

Keil软件中map文件解析

简单的说:map文件是通过编译器编译之后,集程序、数据及IO空间的一种映射文件。

遇到内存越界,或者溢出的情况,可以通过map文件,去确定函数大小,入口地址等一些重要信息。

我们在Keil中最常见的就是在编译之后,编译窗口会显示类似如下一段关于程序和数据大小的信息:
Program Size: Code=1112 RO-data=320 RW-data=0 ZI-data=1632
这一段提示信息其实是汇总了程序和数据的信息,这些信息其实是单个模块汇总而成,在map文件里有详细列表。

如何打开map文件

最直接,也是最简单的办法:双击工程目标,出现map文件(注意双击的工程目标,不要双击到工程,或文件组)。如下图:

image

可以找到map文件位置(Listings文件夹),用编辑器工具打开。

map文件输出内容配置

image

主要包含配置:

  • Memory Map:内存映射
  • Callgraph:图像映射
  • Symbols:符号
  • Cross Reference:交叉引用
  • Size Info:大小信息
  • Totals Info:统计信息
  • Unused Section Info:未调用模块信息
  • Veneers Info:装饰信息

我们可根据自己情况,想要输出什么信息,勾选对应信息即可。

  1. 默认情况,输出所有信息;
  2. 这些配置是一个组合关系;

map文件内容分类

  • Section Cross References:模块、段(入口)交叉引用

    配置中需勾选:Cross Reference

    Section Cross References 指的是各个源文件生成的模块、段(定义的入口)之间相互引用的关系。

    比如:main.o(i.System_Initializes) refers to bsp.o(i.BSP_Initializes) for BSP_Initializes

    意思是:main模块(main.o)中的System_Initializes函数(i.System_Initializes),引用(或者说调用)了bsp模块(bsp.o)中的BSP_Initializes函数。

    提示:

    A.main.o是main.c源文件生成的目标文件模块;

    B.I.System_Initializes是System_Initializes函数的入口。

  • Removing Unused input sections from the image:移除未调用模块

    配置中需勾选:Unuaed Sections Info

    就是我们代码中,没有被调用的模块(或者说函数)会在map文件中生成一个列表。

  • Image Symbol Table:映射符号表

    配置中需勾选:Symbols

  • Memory Map of the image:内存(映射)分布

    配置中需勾选:Memory Map

    内存(映射)分布,内容相对较多,比较重要的一项。

  • Image component sizes:存储组成大小

    其实主要就是对模块进行汇总存储大小信息。

    我们编译工程后,在编译窗口一般会看到类似如下一段信息:

    Program Size: Code=1112 RO-data=320 RW-data=0 ZI-data=1632

    Code:指代码的大小,程序中所有的函数都位于此处。即上述的text段;

    Ro-data:指除了内联数据(inline data)之外的常量数据,程序中所定义的全局常量数据和字符串都位于此处,如const型;

    RW-data:指可读写(RW)、已初始化的变量数据,程序中定义并且初始化的全局变量和静态变量位于此处;

    ZI-data:指未初始化(ZI)的变量数据,程序中定义了但没有初始化的全局变量和静态变量位于此处,Keil编译器默认是把你没有初始化的变量都赋值为例0。即上述的bss段;

    提醒:

    • 值得注意的是,这些参数的单位是Byte
    • Code、Ro-data:位于FLASH中;
    • RW-data、ZI-data:位于RAM中;
    • RW-data已初始化的数据会存储在Flash中,上电会从FLASH搬移至RAM。

    关系如下:

    RO Size = Code + RO Data

    RW Size = RW Data + ZI Data

    ROM Size = Code + RO Data + RW Data

Keil静态库生成和使用方法

关于库

库函数是把函数源代码经过编译后放到库里,供别人使用的一种方式。

比如:将一些常用,或者不想让别人看到源代码的函数(.c文件),一起编译生成一个(.lib)库文件。

调用的时候,需要将(.lib)库函数包含在当前工程,同时需要在头文件(.h文件)中声明函数,然后通过#include头文件,直接调用对应的函数即可。

“.Lib”、“.a”这种库大家可以理解为经过处理的“.c”源文件,只是我们看不到源文件。我们只需要像添加“.c”文件,将其添加到工程即可。

微库(MicroLib)

举例,keil比较常见的库-微库(MicroLib)

我们在代码中调用printf函数打印数据时,就是调用了标准的“微库”。

printf("这是测试\n");

在Keil中使用“微库”,需要配置:Project -> Options for Target -> Target 勾选上“Use Micro LIB”

如下图:

image

同时,如果通过串口打印输出,就需要底层“串口重定义”:

int fputc(int ch, FILE *f)
{
USART1_SendByte((uint8_t)ch);
//对应底层串口输出函数
return ch;
}

什么时候需要使用库

  1. 厂家提供SDK中

    部分源代码可能涉及到特有算法或者某种特殊功能,不对客户公开,便提供库,给用户调用接口使用。

  2. 代码完全模块化

    模块代码的功能在经过无数次验证,并无误后,方便团队的协同开发,这个时候可以将模块代码生成库。

keil如何生成库

Project -> Options for Target -> Output 勾选上“Create Library”即可。
image

注:Keil 生成的库文件是以“.Lib”为后缀的文件

静态库和动态库的区别

Keil生成的库是以“.Lib”为后缀的文件,IAR是以“.a”为后缀的文件,二者都是静态库

  • 静态库:

    就是在编译的时候直接将需要的代码连接进可执行程序中去;

  • 动态库:

    就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。

从上面的描述可以知道,静态库是我们单片机开发者常用的一种,而动态库常用于Linux、Windows等开发场合。

posted @   能跑就行_NPJX  阅读(203)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
点击右上角即可分享
微信分享提示