整理有道云笔记中,关于STM32的笔记
Keil软件中map文件解析
简单的说:map文件是通过编译器编译之后,集程序、数据及IO空间的一种映射文件。
遇到内存越界,或者溢出的情况,可以通过map文件,去确定函数大小,入口地址等一些重要信息。
我们在Keil中最常见的就是在编译之后,编译窗口会显示类似如下一段关于程序和数据大小的信息:
Program Size: Code=1112 RO-data=320 RW-data=0 ZI-data=1632
这一段提示信息其实是汇总了程序和数据的信息,这些信息其实是单个模块汇总而成,在map文件里有详细列表。
如何打开map文件
最直接,也是最简单的办法:双击工程目标,出现map文件(注意双击的工程目标,不要双击到工程,或文件组)。如下图:
可以找到map文件位置(Listings文件夹),用编辑器工具打开。
map文件输出内容配置
主要包含配置:
- Memory Map:内存映射
- Callgraph:图像映射
- Symbols:符号
- Cross Reference:交叉引用
- Size Info:大小信息
- Totals Info:统计信息
- Unused Section Info:未调用模块信息
- Veneers Info:装饰信息
我们可根据自己情况,想要输出什么信息,勾选对应信息即可。
- 默认情况,输出所有信息;
- 这些配置是一个组合关系;
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”
如下图:
同时,如果通过串口打印输出,就需要底层“串口重定义”:
int fputc(int ch, FILE *f)
{
USART1_SendByte((uint8_t)ch);
//对应底层串口输出函数
return ch;
}
什么时候需要使用库
-
厂家提供SDK中
部分源代码可能涉及到特有算法或者某种特殊功能,不对客户公开,便提供库,给用户调用接口使用。
-
代码完全模块化
模块代码的功能在经过无数次验证,并无误后,方便团队的协同开发,这个时候可以将模块代码生成库。
keil如何生成库
Project -> Options for Target -> Output 勾选上“Create Library”即可。
注:Keil 生成的库文件是以“.Lib”为后缀的文件
静态库和动态库的区别
Keil生成的库是以“.Lib”为后缀的文件,IAR是以“.a”为后缀的文件,二者都是静态库。
- 静态库:
就是在编译的时候直接将需要的代码连接进可执行程序中去;
- 动态库:
就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。
从上面的描述可以知道,静态库是我们单片机开发者常用的一种,而动态库常用于Linux、Windows等开发场合。
标签:文件,RW,函数,map,笔记,STM32,模块,data From: https://www.cnblogs.com/npjxcc/p/18021339