当前位置: 首页 > news >正文

【嵌入式】MDK使用sct文件将代码段放入RAM中执行

sct文件即分散加载文件,是ARMCC编译器使用的链接脚本文件,等同于GCC编译器的ld链接脚本。MDK IDE使用的是ARMCC。

支持NorFlash中运行代码(XIP)的MCU例如STM32,一般将所有代码(text段)都放在FLash中,但是Flash的访问速度低于和CPU、RAM,如下图(STM32F103):

当CPU主频为72Mhz的时候,为了弥补CPU和Flash之间的速度差异,需要在访问Flash的时候插入等待周期,否则Flash访问会有问题。因此在整个MCU的运行速度的木桶短板为Flash存储器的访问速度。为了提高代码运行速度,可以将代码装入RAM中,一般MCU中内嵌的SRAM的速度和CPU速度没有差异(不像MPU,中间需要使用cache弥补CPU和外部的DDR RAM之间的速度差异),因此从SRAM中执行代码可以提高运行速度。同时在进行Flash编程擦写的时候,Flash是无法读写的,这时候如果遇到中断的话,是无法进入中断处理函数的,但是如果代码放在RAM中,就没有影响了。

为了将代码放入RAM中运行,需要使用链接脚本控制代码段位置,使用MDK的ARMCC编译器就需要sct分散加载文件。创建一个sct文件main.sct,在RW_IRAM1存储器中添加一个.ramcode段,如下所示:

; *************************************************************

; *** 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 0x00005000  {  ; RW data

   *.o(.ramcode)

   .ANY (+RW +ZI)

  }

}

然后再MDK的Options的Linker选项卡中使用我们自定义的sct文件:

 最后将我们需要放在RAM中的代码使用attribute关键字放入ramcode段中:

__attribute__((section(".ramcode"))) void DMA1_Channel4_IRQHandler()
{
    DMA_ClearFlag(DMA1_FLAG_TC4);
    int i;
    for(i=0;i<sizeof(SPI2_RX_DMA_Buff);i++)
        printf("%c",SPI2_RX_DMA_Buff[i]);
    printf("\r\n");
}

编译之后查看map文件中DMA1_Channel4_IRQHandler的信息:

    DMA1_Channel4_IRQHandler                 0x20000001   Thumb Code   684  main.o(.ramcode)

可以看到DMA1_Channel4_IRQHandler函数的位置位0x20000001(代码的地址最后一位置1表示为thumb代码)。然后找到Execution Region RW_IRAM1:

    Execution Region RW_IRAM1 (Exec base: 0x20000000, Load base: 0x08003ab0, Size: 0x00003ec0, Max: 0x00005000, ABSOLUTE)

    Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x20000000   0x08003ab0   0x000003a0   Code   RO          137    .ramcode            main.o

可以看到ramcode段的Exec Addr为0x20000000,Load Addr为0x08003ab0,即这段代码存放在Flash的0x08003ab0,需加载到0x20000000处运行。加载过程同bss段清零和data段复制类似,在main函数调用之前就会被执行(MDK的ARMCC会自动生成这部分代码,gcc编译器需要自己写)。

实验发现,放在RAM中执行代码相较于Flash,确实有速度提升(没有做定量分析实验)!但是注意代码放在RAM中比较占用RAM空间,并且在Flash中还是会存放代码的,只是在运行时拷贝到RAM中去。

相关文章:

  • 《基于Xilinx的时序分析、约束和收敛》目录与传送门
  • Jackson序列化带有注解的字段的原理浅析
  • 第十届“图灵杯”NEUQ-ACM程序设计竞赛题解(A-I)
  • Linux ALSA 之九:ALSA ASOC Codec Driver
  • 一文读懂JVM类加载机制过程及原理
  • 一文带你入门MyBatis Plus
  • java split()方法 toLowerCase() 方法
  • Ubuntu - command checklist
  • 小程序-模板与配置-WXSS模板样式
  • 小程序-模板与配置-WXML模板语法
  • 群晖NAS安装frp实现内网穿透(非Docker)
  • Linux性能学习(2.1):内存_查看系统内存以及Buffer Cached说明
  • Connext DDS开发指南(5)基本QoS策略
  • MoCoViT: Mobile Convolutional Vision Transformer
  • Harbor安装
  • leetcode解题思路分析(一百三十六)1158 - 1169 题
  • @EnableWebMvc注解让swagger-ui.html无法打开404报错问题及其解决方案(史上最全最详细)
  • Java接口:概述、多实现、多继承、JDK8后接口新增方法
  • 【Java基础】010 -- Java基础综合练习
  • Cesium 和 webgl 加载各类型模型说明
  • 电加热油锅炉工作原理_电加热导油
  • 大型电蒸汽锅炉_工业电阻炉
  • 燃气蒸汽锅炉的分类_大连生物质蒸汽锅炉
  • 天津市维修锅炉_锅炉汽化处理方法
  • 蒸汽汽锅炉厂家_延安锅炉厂家
  • 山西热水锅炉厂家_酒店热水 锅炉
  • 蒸汽锅炉生产厂家_燃油蒸汽发生器
  • 燃煤锅炉烧热水_张家口 淘汰取缔燃煤锅炉
  • 生物质锅炉_炉
  • 锅炉天然气_天燃气热风炉