ZHCAEX1 January 2025 MSPM0G1518 , MSPM0G1519 , MSPM0G3518 , MSPM0G3519 , MSPM0L1227 , MSPM0L1228 , MSPM0L2227 , MSPM0L2228
客户安全代码需要知道应用映像的位置以执行某些安全功能。因此,首先需要进行的工作是为客户安全代码和应用代码配置闪存存储器的布局。相应地更改链接器文件。链接器文件配置示例如下所示。将闪存存储器分为 FLASH_CSC 和 FLASH_APP 两部分。将 SECTIONS.intvecs 设置为 FLASH_CSC 的起始位置,并将相关部分也分配给 FLASH_CSC。
在可交换存储体的配置中,这些闪存存储器保护会自动镜像到两个存储体。这要求 BANK0 和 BANK1 之间的客户安全代码必须相同,并且应用代码从相同的偏移地址开始。
-uinterruptVectors
--stack_size=256
--define=_CSC_SIZE_=(6*1024)
/* Note: SRAM is partitioned into two separate sections SRAM_BANK0 and SRAM_BANK1
to account for SRAM_BANK1 being wiped out upon the device entering any low-power
mode stronger than SLEEP. Thus, this is up to the end-user to enable SRAM_BANK1 for
applications where the memory is considered lost outside of RUN and SLEEP Modes.
*/
MEMORY
{
FLASH_CSC (RX) : origin = 0x00000000, length = _CSC_SIZE_
FLASH_APP (RX) : origin = _CSC_SIZE_, length = (0x00040000 - _CSC_SIZE_)
SRAM_BANK0 (RWX) : origin = 0x20200000, length = 0x00010000
SRAM_BANK1 (RWX) : origin = 0x20210000, length = 0x00010000
BCR_CONFIG (R) : origin = 0x41C00000, length = 0x000000FF /*Boot configuration routine*/
BSL_CONFIG (R) : origin = 0x41C00100, length = 0x00000080 /*Bootstrap loader*/
DATA (R) : origin = 0x41D00000, length = 0x00004000
}
SECTIONS
{
.intvecs : > 0x00000000
.text : palign(8) {} > FLASH_CSC
.const : palign(8) {} > FLASH_CSC
.cinit : palign(8) {} > FLASH_CSC
.pinit : palign(8) {} > FLASH_CSC
.rodata : palign(8) {} > FLASH_CSC
.ARM.exidx : palign(8) {} > FLASH_CSC
.init_array : palign(8) {} > FLASH_CSC
.binit : palign(8) {} > FLASH_CSC
.TI.ramfunc : load = FLASH_CSC, palign(8), run=SRAM_BANK0, table(BINIT)
.vtable : > SRAM_BANK0
.args : > SRAM_BANK0
.data : > SRAM_BANK0
.bss : > SRAM_BANK0
.sysmem : > SRAM_BANK0
.TrimTable : > SRAM_BANK0
.stack : > SRAM_BANK0 (HIGH)
.BCRConfig : {} > BCR_CONFIG
.BSLConfig : {} > BSL_CONFIG
.DataBank : {} > DATA
}
以下示例展示了如何根据客户安全代码的启动序列来实现存储体交换功能。软件首先会检查 INITDONE 位。如果尚未发出 INITDONE,请在此处设置安全代码。在这种情况下,首先通过调用 DL_SYSCTL_executeFromUpperFlashBank() 函数来配置存储体交换功能。然后,延迟适当的时间,并通过调用 DL_SYSCTL_issueINITDONE () 函数来发出 INITDONE 位。调用 DL_SYSCTL_issueINITDONE () 函数会触发 SYSRST。在 SYSRST 之后,MCU 在 BANK1 处开始运行。客户还可以在代码中添加存储体交换条件。如果条件匹配,则软件会调用存储体交换函数并运行 BANK1 应用项目。客户可以在代码中添加其他 CSC 函数。别忘了在所有 CSC 函数执行完后发出 INITDONE。系统复位后,如果未启用存储体交换功能,则软件可以通过调用 start_app () 函数来运行位于 BANK0 中的应用项目。
int main(void)
{
SYSCFG_DL_init();
if (!(DL_SYSCTL_isINITDONEIssued())) {
if(bankswap == true){ // Add bank swap conditions if needed
DL_SYSCTL_executeFromUpperFlashBank(); // Set swap bank0 to bank1
delay_cycles(160);
DL_SYSCTL_issueINITDONE(); // Issue INITDONE to trigger System Reset -> swap to bank1
}else
{
// Add other CSC function if needed
DL_SYSCTL_issueINITDONE(); // Then issue INITDONE to trigger System Reset
}
}else
{
start_app((uint32_t *) (0x1800)); // Jump to BANK0 app start address
}
}
下面提供了 start_app() 函数的示例。输入参数是应用的起始地址。链接器文件配置中的存储器映射已更改。在这种情况下,BANK0 中的应用代码从 0x1800 开始。软件会将 SP 值和复位向量复位为应用代码的向量表。然后,将 PC 设置为应用代码的复位处理程序地址。该过程使 MCU 开始运行 BANK0 中的应用代码。
static void start_app(uint32_t *vector_table)
{
/* Reset the SP with the value stored at vector_table[0] */
__asm volatile(
"LDR R3,[%[vectab],#0x0] \n"
"MOV SP, R3 \n" ::[vectab] "r"(vector_table));
/* Set the Reset Vector to the new vector table (Resets to 0x000) */
SCB->VTOR = (uint32_t) vector_table;
/* Jump to the Reset Handler address at vector_table[1] */
((void (*)(void))(*(vector_table + 1)))();
}