guiyan 发表于 2024-1-13 16:31

APM32F4xx Keil MDK 散列文件sct的使用分享

本帖最后由 guiyan 于 2024-1-13 16:31 编辑

前言本文旨在APM32F4xx系列GPIO例程Keil MDK环境下,如何自定义散列文件stc,实现各数据段分区管理,存放在指定内存位置。一 程序文件中的分区
[*]Code:即代码域,它指的是编译器生成的机器指令。
[*]RO_data:ReadOnly data,即只读数据域,它指程序中用到的只读数据,全局变量,例如C语言中const关键字定义的全局变量就是典型的RO-data。
[*]RW_data:ReadWrite data,即可读写数据域,它指初始化为“非0值”的可读写数据,程序刚运行时,这些数据具有非0的初始值,且 运行的时候它们会常驻在RAM区,因而应用程序可以修改其内容。 例如全局变量或者静态变量,且定义时赋予“非0值”给该变量进行初始化。
[*]ZI_data:ZeroInitialie data,即0初始化数据,它指初始化为“0值”的可读写数据域,它与RW_data的区别是程序刚运行时这些数据初始值全都为0,而 后续运行过程与RW-data的性质一样,它们也常驻在RAM区,因而应用程序可以更改其内容。 包括未初始化的全局变量,和初始化为0的全局变量。
RW_data和ZI_data,在程序运行的开始阶段,就需要从Flash中复制到RAM中。
[*]RO:只读区域,包括RO_data和code。
散列文件sct介绍详细可参考官方文档ARM Compiler v5.06 for µVision armlink User Guide的Scatter File Syntax
官方文档路径在Keil安装目录:
C:\Keil_v5\ARM\Hlp\armtools.chm
C:\Keil_v5\ARM\Hlp\DUI0377G_02_mdk_armlink_user_guide.pdf

散列文件sct总览简单分析:
[*]加载域 LOAD_ROM_1(起始地址为0x0000) 和 LOAD_ROM_2(起始地址为0x4000)
意思是该区域数据全部都会下载到以起始地址开始的内存空间中。
[*]执行域 EXEC_ROM_1(起始地址为0x0000) 和 EXEC_ROM_2(起始地址为0x4000)
意思是输入段的数据,会从这个地址开始执行。
有2种情况:

[*]直接从Flash加载域执行
[*]把Flash加载域的数据,复制到RAM中,从RAM执行
[*]输入段描述
program1.o (+RO):RO属性的数据
program1.o (+RW,+ZI): RW和ZI的数据
program2.o (+RO):RO属性的数据
program2.o (+RW,+ZI): RW和ZI的数据
综上:
就是从0x0000开始下载program1.o的RO数据,并从0x0000执行;
从RO数据结束的地方,紧接着下载program1.o RW数据,但程序运行时,会把RW和ZI数据复制到0x18000开始的内存中执行。
program2.o RO、RW和ZI同理。前缀符 :gdef: 的使用在散列文件sct中,可以通过使用前缀符 :gdef: 来存放全局符号( 同个C文件所有全局变量 或者全局函数名)到特定位置上。/* 示例1 Delay_ms函数*/
void Delay_ms(__IO u32 nms)
{
    SysTick_Config(SystemCoreClock / 1000);

    cntMs = nms;
    while(cntMs != 0);
}

;Delay_ms function
LR_IROM2 0x08005000 0x00004000{    ; load region size_region
ER_IROM2 0x08005000 0x00004000{; load address = execution address
    *(:gdef:Delay_ms)//Delay_ms函数存放到固定位置0x08005000地址上
}
}查看map文件:数据段分区管理应用在APM32F4xx系列GPIO例程中,修改sct文件,修改如下:; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

;vctor
LR_ROM_VCTOR 0x08000000 0x00001000{    ; load region size_region
ER_ROM_VCTOR 0x08000000 0x00001000{; load address = execution address
   *.o (RESET, +First)
}
}

;entry
LR_ROM_ENTRY 0x08001000 0x00000100{    ; load region size_region
ER_ROM_ENTRY 0x08001000 0x00000100{; load address = execution address
   *(InRoot$Sections)
}
}

;code
LR_ROM_CODE 0x08002000 0x00004000{    ; load region size_region
ER_ROM_CODE 0x08002000 0x00004000{; load address = execution address
   .ANY (+CODE)
}
}

;const data
LR_ROM_CONST 0x08003000 0x00002000{    ; load region size_region
ER_ROM_CONST 0x20001000 0x00002000{; load address = execution address
   .ANY (+CONST)
}
}

;rw data
LR_ROM_RW 0x08004000 0x00002000{    ; load region size_region
ER_ROM_RW 0x20000000 0x00002000{; load address = execution address
   .ANY (+RW +ZI)
}
}

;Delay_ms function
LR_IROM2 0x08005000 0x00004000{    ; load region size_region
ER_IROM2 0x08005000 0x00004000{; load address = execution address
    *(:gdef:Delay_ms)
}
}查看map文件,分区管理成功,并能下载程序正常运行。例程请见附件。





kai迪皮 发表于 2024-1-15 10:54

学习到了。
页: [1]
查看完整版本: APM32F4xx Keil MDK 散列文件sct的使用分享