keil Scatter File调试小记
前言
最近一个项目要用到分散加载文件sct进行分散烧录Code,一点调试实测发现在此随手小记,记录分享,仅供参考,如有错误,欢迎探讨指正。
Sct可以在keil通过Target中GUI配置,也可以通过Linker单独sct文件配置,其他基础知识此处暂不赘述。
调试背景
Code数据量:0x8C10;
芯片ROM起始地址与大小:0x0,0x10000;
使用Sct内容:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00000000 0x00001000 { ; load region size_region
ER_IROM1 0x00000000 0x00001000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x10000000 0x00001000 { ; RW data
.ANY (+RW +ZI)
}
}
LR_IROM2 0x00005000 0x0000A000 {
ER_IROM2 0x00005000 0x0000A000 { ; load address = execution address
.ANY (+RO)
}
}
在编译后生成有两个bin文件:ER_IROM1,ER_IROM2。
调试一(IROM1变化)
保持IROM2 0x00005000 0x0000A000配置不变,分别修改IROM1如下配置,查看Flash实际烧录占用大小情况:
- IROM1 0x00000000 0x00001000
ROM1中0x1000实际占用0~0x537。 - IROM1 0x00000000 0x00002000
ROM1中0x2000实际占用0~0x83F。 - IROM1 0x00000000 0x00004000
ROM1中0x4000实际占用0~0x184F。
1)ROM2中实际占用也随之变化,但与ROM1中总数据量合计为0x8C10,与单独烧录到ROM1中占用大小一致。
2)并且通过对比烧录数据内容发现,数据分布情况呈现为小块状无序分配,首尾部分仍在ROM1,中间部分优先存储ROM2一部分,剩余存储ROM1。
3)说明keil在编译时已综合根据ROM1和ROM2分配大小与代码函数编译大小等情况自动重新进行调整合理分布排列使用。
4)而且保持ROM2大小不变的情况下,改变ROM1大小增大,则烧录实际占用ROM1的大小也呈现比例增加。
调试二(IROM2变化)
保持IROM1 0x00000000 0x00009000配置不变,分别修改IROM2如下配置,查看Flash实际烧录占用大小情况;
- IROM2 0x0000A000 0x00001000
ROM1中0x9000实际占用0~0x8843,
ROM2中0x1000实际占用0xA000~0xA3CB。 - IROM2 0x0000A000 0x00005000
ROM1中0x9000实际占用0~0x6847,
ROM2中0x1000实际占用0xA000~0xC3D3。
1)此处也佐证了“调试一”中的推测,ROM1或ROM2任一变更分配大小,均会导致编译烧录时实际占用大小呈正相关调整比例的变化,但总数据量大小基本保持一致。
- 删除IROM2配置
ROM1中0x9000实际占用0~0x8C0F。 - 用于与“调试二”第一项测试及上一项测试对比:
保持IROM2 0x0000A000 0x00001000配置不变,修改IROM1 0x00000000 0x00008000
编译时报错:Load region LR_IROM1 size (32840 bytes) exceeds limit (32768 bytes). Region contains 625 bytes of padding and 0 bytes of veneers (total 625 bytes of linker generated content).
2)说明即使总大小刚够存放Code数据使用,单独ROM1正常,但若分散使用IROM1和IROM2则可能会需要额外的一点空间(也可能与编译时无法排布数据块为合理状态或者内存对齐或链接器有关)。
调试三(IROM1/IROM2均配置但Code全在ROM1)
思路与目标:IROM1/IROM2均配置,增加IROM1配置大小,直到编译烧录时Code实际占用仅在ROM1。
- IROM1 0x00000000 0x0000A000,IROM2 0x0000B000 0x00004000
ROM1中0xA000实际占用0~0x7847,
ROM2中0x4000实际占用0xB000~0xC3CB。 - IROM1 0x00000000 0x0000B000,IROM2 0x0000C000 0x00003000
ROM1中0xB000实际占用0~0x8843,
ROM2中0x3000实际占用0xC000~0xC3CB。 - IROM1 0x00000000 0x0000C000,IROM2 0x0000D000 0x00002000
ROM1中0xC000实际占用0~0x8C0F,
ROM2中0x2000实际占用0。
1)由此一点推测,在IROM1/IROM2均配置时,至少IROM1需比实际编译Code数据量多出12k(0xBC10-0x8C10=0x3000),才可使得keil在编译时排布完全使用ROM1中而不使用ROM2。
小结
经测,无论如何ROM1和ROM2大小分配,编译成功并烧录后,程序运行和功能均正常。
调试发现与推测汇总:
1)ROM1或ROM2任一变更分配大小,均会导致编译烧录时实际占用大小呈正相关调整比例的变化。
2)无论是否使用分散多个ROM,编译Code总数据量大小基本保持一致。
3)数据分布情况呈现为小块状无序分配,首尾部分仍在ROM1,中间部分优先存储ROM2一部分,剩余存储ROM1。
4)若分散使用IROM1和IROM2则可能会需要额外的一点空间。
5)在IROM1/IROM2均配置时,至少IROM1需比实际编译Code数据量多出12k(0x3000),才可使得keil在编译时排布完全使用ROM1中而不使用ROM2。
当然,由于本文测试样本不多,且测试量不大,可能推测观点有一定的局限性。欢迎探讨或指正。