本帖最后由 千岁寒 于 2018-11-5 13:00 编辑
1、什么是分散加载
简单来说就是让编译器高速MCU内核哪里存的是代码、哪里存的是数据,去哪个特定的地址找到下一步需要运行的函数,就是高速编译器把每一个编译好的函数、数据放到具体的哪一个物理地址。
2、分散加载常见应用场景
* Bootloader & 程序升级
Bootloader的原理就简单来说在MCU的Flash里面同时摆放2个(或多个)不同工程的程序,一个Bootloader程序和一个用户程序,那么这就需要调整分散加载文件,以达成在一个Flash里面同时摆放两个不同程序的目的。
程序升级都是为了增加一个小功能或修复一个小BUG,不需要全部升级而是只升级一点点。当然要实现这个功能同样需要分散加载的配合,把可能会后续升级的部分函数或数据事先分配好空间,留好空间上的余量,这些都需要分散加载来完成。
* 加速程序运行速度(如:对速度有较高要求的算法等、RTOS kernel)
在SRAM中运行的程序要比在XIP Flash中执行要快,性能提升明显。
* 访问扩展存储&对存储区的划分
如果要把外扩的存储用于运行代码/扩展RW数据段等用途,简单来说就是把片内地址映射到片外,需要按照寻址空间的方式来访问扩展存储的话,比如扩展Nor-Flash、扩展SDRAM、扩展SRAM等,那就需要分散加载配合。(只作存储数据的话,分散加载不是必要的!!!)
3、分散加载的基本结构定义以及分散加载的目的
Code段:表示程序代码部分
RO-data段:程序定义的所有常量以及const类型数据
RW-data段:已经初始化的所有静态变量
ZI-data段:未初始化的静态变量
RO段:指Code以及RO-data的统称
具体分布可查看对应的*.map文件。
RW+ZI数据段最终运行时会占用片内SRAM或外扩的RAM存储器,而Code+RO-data+RW-data数据最终会产生对片内Flash的占用或外扩程序存储区的占用。
所以分散加载的根本目的就是:
* 指引把RO-data数据段、RW数据段从片内程序存储区里面(一般是片内Flash),搬到片内程序运行区(一般是片内SRAM);
* 在片内程序运行区(一般是片内SRAM)内分配ZI数据段运行需要的空间并把这段数据初始化为0;
* 初始化堆栈;
* 对于有些指定加载到程序运行区(一般是片内SRAM)的RO数据段,把他们加载到程序运行区(一般是片内SRAM)里面。
{ 类比:这个和使用的电脑运行操作系统或者软件原理类似,电脑就是把硬盘里面的操作系统加载到内存里面,然后CPU从内存里面取数据以及程序指令来运行的。}
TIP:
RW以及ZI数据段的初始化是在分散加载过程中完成的,也就是在__main中完成的,比如你定义一个全局变量,并给它赋值,只有在__main结束后你才能看到这个全局变量被赋值成功的,也就是说在__main之前,使用全局变量是行不通的。
整理参考: https://blog.csdn.net/weixin_39118482/article/details/79849133 |