默认情况下,我们都是通过 MDK 的 option 选项设置 Flash 和 RAM 大小,如图1

图1

这种情况下,不方便用户将变量定义到指定的 CCM 或者 SDRAM 中。而使用attribute指定具体地址又不方便管理。默认设置下编译工程完成后,会在文件夹【Objects】(本工程的路径)中会自动生成一个后缀为.sct的文件【output.sct】,如图2

图2

打开自动生成的文件【output.sct】,如代码1

代码1; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

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

LR_IROM1 0x08000000 0x00200000 { ; load region size_region

ER_IROM1 0x08000000 0x00200000 { ; load address = execution address

*.o (RESET, +First)

*(InRoot$$Sections)

.ANY (+RO)

.ANY (+XO)

}

RW_IRAM1 0x20000000 0x00020000 { ; RW data

.ANY (+RW +ZI)

}

}

我们就是通过更改此.sct文件内容,并把它重定向,使得MDK能够分散加载方式管理多块内存。更改后的代码,如代码2

代码2; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

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

LR_IROM1 0x08000000 0x00200000 { ; load region size_region

ER_IROM1 0x08000000 0x00200000 { ; load address = execution address

*.o (RESET, +First)

*(InRoot$$Sections)

.ANY (+RO)

}

RW_IRAM1 0x20000000 0x00020000 { ; RW data - 128KB DTCM

.ANY (+RW +ZI)

}

RW_IRAM2 0x24000000 0x00080000 { ; RW data - 512KB AXI SRAM

*(.RAM_D1)

}

RW_IRAM3 0x30000000 0x00048000 { ; RW data - 128KB SRAM1(0x30000000) + 128KB SRAM2(0x3002 0000) + 32KB SRAM3(0x30040000)

*(.RAM_D2)

}

RW_IRAM4 0x38000000 0x00010000 { ; RW data - 64KB SRAM4(0x38000000)

*(.RAM_D3)

}

}

对比代码1,代码2增加了3个供调用的RAM区域。代码2的逐行注解如下。

第5行至第6行:LR_IROM1是Load Region(加载域),ER_IROM1是Execution Region(执行域)。首地址都是 0x0800 0000,大小都是 0x0020 0000,即 STM32H7的Flash地址和对应大小。加载域是程序在Flash 中的实际存储,执行域是芯片上电后的运行状态,如图3

图3

第7行:在启动文件 startup_stm32h743xx.s 有个段名为 RESET 的代码段,主要存储了中断向量表。这里是将其存放在Flash的首地址。

第8行:这里是将 MDK 的一些库文件全部放在根域,比如__main.o, _scatter.o, _dc.o。

第9行:将目标文件中所有具有 RO 只读属性的数据放在这里,即ER_IROM1。

第12至13行:RW_IRAM1 是执行域,配置的是 DTCM,首地址 0x2000 0000,大小128KB。将目标文件中所有具有 RW和ZI数据放在这里。

第16至17行:RW_IRAM2 是执行域,配置的是D1域的AXI SRAM,首地址 0x24000000,大小512KB。给这个域取名为.RAM_D1。这样通过attribute((section(“name”)))将其分配到这个RAM域。

第20至21行:RW_IRAM3 是执行域,配置的是D2域的SRAM1,SRAM2和SRAM3,首地址0x30000000,共计大小 288KB。 给这个域取名为.RAM_D2。这样通过attribute((section(“name”)))将其分配到这个RAM域。

第24至25行:RW_IRAM3 是执行域,配置的是D3域的SRAM4,首地址 0x38000000,共计大小64KB。给这个域取名为.RAM_D3。这样通过attribute((section(“name”))) 将其分配到这个RAM域。

注:关于XO、RO、RW、ZI术语解释摘自MDK帮助文档

One execute-only (XO) section if the execution region contains only XO sections.

One RO section if the execution region contains read-only code or data.

One RW section if the execution region contains read-write code or data.

One ZI section if the execution region contains zero-initialized data.

至此,.sct文件制作完毕。下面将.sct文件改名存放在工程文件的根目录任意位置。然后进行重定向,如图4

图4

至此,已经配置完毕,编写应用程序进行验证,如伪代码3

伪代码3// mian函数前声明

/* 定义在512KB AXI SRAM里面的变量 */

__attribute__((section (".RAM_D1"))) uint32_t AXISRAMBuf[10];

__attribute__((section (".RAM_D1"))) uint16_t AXISRAMCount;

/* 定义在128KB SRAM1(0x30000000) + 128KB SRAM2(0x30020000) + 32KB SRAM3(0x30040000)里面的变量 */

__attribute__((section (".RAM_D2"))) uint32_t D2SRAMBuf[10];

__attribute__((section (".RAM_D2"))) uint16_t D2SRAMount;

/* 定义在64KB SRAM4(0x38000000)里面的变量 */

__attribute__((section (".RAM_D3"))) uint32_t D3SRAMBuf[10];

__attribute__((section (".RAM_D3"))) uint16_t D3SRAMCount;

// main函数中调用

switch (ucKeyCode)

{

case KEY_DOWN_K1: /* K1键按下,操作AXI SRAM */

AXISRAMBuf[0] = AXISRAMCount++;

AXISRAMBuf[5] = AXISRAMCount++;

AXISRAMBuf[9] = AXISRAMCount++;

printf("K1键按下, AXISRAMBuf[0] = %d, AXISRAMBuf[5] = %d, AXISRAMBuf[9] = %d\r\n",

AXISRAMBuf[0],

AXISRAMBuf[5],

AXISRAMBuf[9]);

break;

case KEY_DOWN_K2: /* K2键按下,操作D2域的SRAM1,SRAM2和SRAM3 */

D2SRAMBuf[0] = D2SRAMount++;

D2SRAMBuf[5] = D2SRAMount++;

D2SRAMBuf[9] = D2SRAMount++;

printf("K2键按下, D2SRAMBuf[0] = %d, D2SRAMBuf[5] = %d, D2SRAMBuf[9] = %d\r\n",

D2SRAMBuf[0],

D2SRAMBuf[5],

D2SRAMBuf[9]);

break;

case KEY_DOWN_K3: /* K3键按下,操作D3域的SRAM4 */

D3SRAMBuf[0] = D3SRAMCount++;

D3SRAMBuf[5] = D3SRAMCount++;

D3SRAMBuf[9] = D3SRAMCount++;

printf("K3键按下, D3SRAMBuf[0] = %d, D3SRAMBuf[5] = %d, D3SRAMBuf[9] = %d\r\n",

D3SRAMBuf[0],

D3SRAMBuf[5],

D3SRAMBuf[9]);

break;

default:

/* 其它的键值不处理 */

break;

至此,可以看到程序正常运行,stm32h7“分散加载方式管理多块内存”操作完毕!

stm32h7内存分配_stm32h7“分散加载方式管理多块内存”相关推荐

  1. 13、MDK分散加载方式管理多块内存

    MDK分散加载: 默认情况下是通过MDK的option选项设置Flash和RAM大小,这种情况下所有的管理工作都是编译来处理的, MDK自动生成的分散加载文件:H7_ProjectTest.sct ; ...

  2. app与bootloader共享内存的方法(分散加载文件)

    app要升级时要通知bootloader,然后进入bootloader模式,app要如何通知bootloader呢?以前用了写入升级标志到eeprom的方式,然后bootloader再去读取,这是一种 ...

  3. STM32分散加载文件

    通过使用分散加载机制,可以为链接器指定映像的内存映射.分散加载为您提供了对映像组建分组和位置的全面控制.分散加载可以用于简单映像,但它通常仅用于具有复杂内存映射的的映像,即多个区在加载和执行时分散在内 ...

  4. x210开发板的三种启动方式(三星推荐的,分散加载,uboot采用的)

    1.三星推荐的启动方式 (1)将bl1放在在SRAM中运行,将bl2也在SRAM中运行,就像datasheet中描述那样. (2)bootloader必须小于96KB并大于16KB,假定bootloa ...

  5. H750移植rt_thread操作系统完整工程分享,包括外部FLASH分散加载文件

    一.移植注意事项 1.在运行外部FLASH存储的代码之前首先要初始化QSPI进入内存映射模式,参考代码: //QSPI进入内存映射模式(执行QSPI代码必备前提,为了减少引入的文件, //除了GPIO ...

  6. sct分散加载文件格式与应用

    *.sct分散加载文件是根据芯片内部FLASH和SRAM存储器概况生成的配置文件,链接器根据该文件的配置分配各个节区地址,生成分散加载代码,通过修改该文件可以定制节区的具体存储位置.例如控制代码的加载 ...

  7. 【IoT】STM32 分散加载文件 .sct 解析

    1.STM32 启动文件与 .sct 文件分析 1) 定义STACK段,{NOINIT,读写}:分配一段内存大小为0.5K; 2) 定义HEAP段, {NOINIT,读写}:分配一段内存大小为1K; ...

  8. keil的sct文件_STM32 分散加载文件 .sct 解析

    1.STM32 启动文件与 .sct 文件分析 1) 定义STACK段,{NOINIT,读写}:分配一段内存大小为0.5K; 2) 定义HEAP段, {NOINIT,读写}:分配一段内存大小为1K; ...

  9. keil的sct文件_Keil sct分散加载文件

    博主是个还没入门的弱菜,老师让查资料所以我把自己找的资料整理一下搁在这里方便以后查阅用的,自己并没有试过. 如有错误,欢迎指正. 参考资料: 首先介绍几个概念: 1.ARM映像文件 ARM映像文件是一 ...

最新文章

  1. 数据库 ' 库名' 已打开,并且一次只能有一个用户访问。 (Microsoft SQL Server,错误: 924)
  2. 收藏!超全机器学习资料合集!(附下载)
  3. linux中如何授权限,Linux系统下,为普通用户授权。
  4. WindowsServer2012史记4-重复数据删除的魅力
  5. RT-Thread智能音箱音频应用实践
  6. axure rp 创建弹框_如何在Axure RP 9中创建交换机
  7. Leaf服务器框架从入门到放弃(一)认识Leaf和安装Leaf环境
  8. C/C++的readdir和readdir_r函数(遍历目录)
  9. git进入项目目录 windows_Windows下Git 怎么整个文件夹目录上传到代码仓库(不论GitHub、GitLab、Gitee、DevCloud)...
  10. oracle出现The Network Adapter could not establish the connection的问题
  11. arraylist 初始化_ArrayList - 遍历ArrayList的三种方法
  12. 望城2019年华为软件云项目_今天,华为、京东两大项目在长沙开工
  13. laravel实现mysql读写分离
  14. perl中uc,lc,ucfirst,lcfirst的用法(转载)
  15. 如何在AD上重定向电脑加域后默认保存位置?
  16. 编写一个函数,输入n为偶数时,调用函数求1/2+1/4+…+1/n,当输入n为奇数时,调用函数求1/1+1/3+…+1/n
  17. Blog选址,可实现通过xml-rpc标准进行远程离线发布的Blog服务商(BSP)测评
  18. 内存与IO,磁盘IO,网络IO
  19. 春节档低迷,中国影视的好内容饥渴症如何解?
  20. 恶狗一样的彩虹QQ!

热门文章

  1. 来点硬件知识吧,今天求职吃亏了!
  2. 101个Google技巧——Google技巧的终极收集
  3. 微信小程序遇到的那些坑
  4. iphoneX的适配问题
  5. paramiko学习笔记
  6. vs2012中对于entity framework的使用
  7. Python的Boolean操作
  8. 线性表--数组实现+模板+迭代器
  9. 使用Zabbix的SNMP trap监控类型监控设备的一个例子
  10. 设计程序时,注意和外系统连携相关的处理