使用Keil将STM32部分程序放在RAM中运行

  1. 手动分配RAM区域,新建.sct文件,定义RAM_CODE区域,并指定其正确的起始地址和大小。
c 复制代码
; *************************************************************
; *** 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文件

  1. 手动标记函数:

在函数定义中使用 attribute((section(".RAM_CODE"))) 明确标记需要放置在RAM中的函数。

c 复制代码
__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:

c 复制代码
//修改前.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
c 复制代码
//修改后启动代码(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+,修改后代码如下

c 复制代码
//修改后启动代码(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
  1. 重新编译项目
    在Keil中选择"Rebuild All"来重新编译项目。
  2. 查看生成的.map文件,确保目标函数被正确放置在RAM中。
相关推荐
LNN20229 分钟前
STM32H7 + 迪文屏 DGUS 开发实战:从零构建工业级时间设置界面
stm32·单片机·嵌入式硬件
Z文的博客3 小时前
嵌入式MCU与迪文屏通信:DMA+环形FIFO+变长队列+状态机完整手册
stm32·单片机·串口·dma·中断·串口dma·嵌入式单片机
BackCatK Chen4 小时前
STM32保姆级入门教程|第7章:串口通信(USART)收发数据 + printf重定向打印调试(功能超详细+CubeIDE手把手)
stm32·串口通信·usart·stm32cubeide·printf重定向·嵌入式调试·中断接收
12.=0.4 小时前
【stm32_5】Systick嘀嗒定时器、解析时钟源、分析时钟树、应用Systick设计延时
c语言·stm32·单片机·嵌入式硬件
达不溜的日记5 小时前
CAN总线网络传输层CanTp详解
网络·stm32·嵌入式硬件·网络协议·网络安全·信息与通信·信号处理
森利威尔电子-6 小时前
森利威尔SL6129兼容 AL8805 / AL8806,输入电压 5.5V - 30V,最大输出电流 1.2A
单片机·嵌入式硬件·集成电路·芯片·电源芯片
FreakStudio6 小时前
嘉立创开源:应该是全网MicroPython教程最多的开发板
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy
qq_441685756 小时前
CC26xx开发 第一节 前期准备
嵌入式硬件
史蒂芬_丁7 小时前
TI F28P65 使用 ePWM 模块模拟 SPI 时钟的详细方法
单片机·嵌入式硬件·fpga开发
LinuxRos7 小时前
I2C子系统与驱动开发:从协议到实战
linux·人工智能·驱动开发·嵌入式硬件·物联网