- 手动分配RAM区域,新建.sct文件,定义RAM_CODE区域,并指定其正确的起始地址和大小。
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00010000 { ; load region size_region
ER_IROM1 0x08000000 0x00010000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x4000 { ; RW data in RAM
.ANY (+RW +ZI)
}
ER_RAM_CODE 0x20004000 0x1000 { ; Execution region in RAM for specific functions
*.o (.RAM_CODE)
}
}
在keil中,打开“Options for Target”,选择“Linker”选项卡,手动选择新生成的.sct文件
2. 手动标记函数:
在函数定义中使用 attribute((section(“.RAM_CODE”))) 明确标记需要放置在RAM中的函数。
__attribute__((section(".RAM_CODE")))
void SPI1_Nss_High(void)
{
HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);
}
__attribute__((section(".RAM_CODE")))
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if (PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
}
}
3.修改启动文件,将指定代码从Flash搬运到RAM:
//修改前.s启动代码
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
//修改后启动代码(cortex-M3)
RAM_CODE_START EQU 0x20004000 ; RAM????????
RAM_CODE_SIZE EQU 0x1000 ; RAM??????
FLASH_CODE_START EQU 0x08000000
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
; Copy RAM code section from Flash to RAM
LDR R1, =FLASH_CODE_START
LDR R2, =RAM_CODE_START
LDR R3, =RAM_CODE_SIZE
Copy_RAM_Code
LDRB R0, [R1], #1
STRB R0, [R2], #1
SUBS R3, R3, #1
BNE Copy_RAM_Code
; Enter the C runtime environment
LDR R0, =__main
BX R0
ENDP
如果单片机内核是cortex-m0+,修改后代码如下
//修改后启动代码(cortex-M0+)
RAM_CODE_START EQU 0x20006000 ; RAM????????
RAM_CODE_SIZE EQU 0x1000 ; RAM??????
FLASH_CODE_START EQU 0x00000000
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
; Copy RAM code section from Flash to RAM
LDR R1, =FLASH_CODE_START
LDR R2, =RAM_CODE_START
LDR R3, =RAM_CODE_SIZE
Copy_RAM_Code
LDRB R0, [R1]
STRB R0, [R2]
ADDS R1, R1, #1
ADDS R2, R2, #1
SUBS R3, R3, #1
BNE Copy_RAM_Code
; Enter the C runtime environment
LDR R0, =__main
BX R0
ENDP
- 重新编译项目
在Keil中选择“Rebuild All”来重新编译项目。 - 查看生成的.map文件,确保目标函数被正确放置在RAM中。