
一、什么是散列文件 我们可以看到,在编译过程中有多个.o文件,而最后生成的只是一个文件,那么这些文件要怎么以什么方式生成一个文件呢?说的专业一点,这个过程就是链接,而在Keil-MDK下就是使用散列文件来指导链接的。 如图所示,将【Use Memory Layout from Target Dialog】勾选上 ![]() 然后重新编译,我们就可以在【Objects】目录下得到一个.sct文件如下所示 ![]() 二、散列文件的格式 如下所示,一个散列文件由一个或多个Load region组成,一个Load region中含有一个或多个Execution region,一个Execution region中又含有一个或多个Input section。 首先,LR_IROM1是Load region的区域名,紧接着0x08000000是其加载地址,然后0x00080000是其区域最大容量; 然后,ER_IROM1是Execution region的区域名,紧接着0x08000000是其可执行地址,也可以叫链接地址,然后0x00080000也是其区域最大容量; ![]() 接下来就是各种文件的链接方式了,解释如下
三、分析散列文件 打开uart.dis文件,可以看到有个__main,这就是keil添加的可执行代码,因为我们使用了main函数,所以这段代码被添加进去了, ![]() 我们将我们代码中的main改为mymain,可以看到,这段代码没有了 ![]() 我们在main.c中添加如下所示变量定义, ![]() 然后编译,打开uart.dis文件,可以看到,myconst变量被链接到0x08…开头的地址,即ER_IROM1 区域,而my、mydate和myzero即被链接到0x20…开头的地址,即RW_IRAM1 区域;与之相对应的,ER_IROM1 区域为该STM32的Flash地址,RW_IRAM1 区域为该STM32的RAM地址。 ![]() 然后我们再看一下,uart.dis文件中,ER_IROM1 区域的最后一个位置0x080001ac存放的即我们定义的只读变量myconst ![]() 但我们使用STM32Cubeprg打开uart.hex文件可以看到,在0x080001ac后还有三个位置,而这三个位置存放的刚好就是我们定义的三个my、mydate和myzero变量。 ![]() 实际上,对于在STM32F103这类资源紧缺的单片机芯片中: 代码段保存在Flash上,直接在Flash上运行(当然也可以重定位到内存里) 数据段暂时先保存在Flash上,然后在使用前被复制到内存里(只读数据段不复制) 四、验证数据段的存放 修改main.c如下所示
编译烧录运行,可以看到,只有myconst变量值是正确的,其他三个变量值都是错误的,这是因为我们并没有将那三个变量的值从Flash上复制到内存里,所以读取出来的只是上电后该RAM地址的一个随机值。 ![]() 然后再添加一下地址的打印 ![]() 编译烧录运行,可以看到,确实只有myconst变量值是保存在Flash的,其他三个变量值都是在内存里的 ![]() 另外我们也可以顺便看一下栈地址,在mymain函数里定义一个变量并打印其地址
编译烧录运行,可以看到,其地址确实在我们设置的栈中 ![]() ———————————————— 转载:Willliam_william |
STM32 GUI LTDC 最大像素时钟评估方法
【2025·STM32峰会】GUI解决方案实训分享1-对LVGL咖啡机例程的牛刀小试以及问题排查
OpenBLT移植到STM32F405开发板
为什么要先开启STM32外设时钟?
【STM32MP157】从ST官方例程中分析RPMsg-TTY/SDB核间通信的使用方法
【经验分享】STM32实例-RTC实时时钟实验④-获取RTC时间函数与中断服务函数
STM32 以太网 MAC Loopback 的实现
STM32功能安全设计包,助力产品功能安全认证
基于STM32启动过程startup_xxxx.s文件经验分享
HRTIM 指南