最近搞Dialog的BLE SDK,发现空间不够了,询问原厂,得知可以通过调整分散加载文件而增加空间,一方面是有42KB+8KB的硬件基础,另一方面是原有的程序限制为38KB+8KB。故顺便学习了下把一个程序存放在不同的存储空间的问题。

  简单的单片机是不用了解程序分散加载机制的,至少我搞了四五年(加上大学三年哈)没有碰到要特别需要了解的,空间不够换更大容量的单片机嘛。期间仅仅是听说过而已。还听说过搞能够跑Linux的开发板裸奔的时候需要了解下,因为程序比较大,为了兼顾性能,需要把程序分别存放在NAND Flash、NOR Flash、SDRAM等。

1、知识普及,怎么解读分散加载文件

  分散加载,当然是把一个整体分成几个部分,放在不同的位置。怎么分割呢?可以按照RO、RW、ZI属性区分,还可以自定义代码属性,然后根据自定义属性划分。这个在后面介绍怎么自定义代码属性。

  我可以按照代码属性随便放几个位置就可以嘛?有什么放置依据嘛?如果空间够大,CPU取指令速度差不多或没要求,可以随便放。当然,怎么放也是有一些规则的。比如RO属性的代码,放在ROM里,CPU只是读出来而已,比如RW和ZI属性的CPU要频繁的读写,可以放在RAM里,甚至是CPU的寄存器里,可以提高CPU的处理速度。对!这些规则的目的只有一个:怎么提高CPU的效率!

  分散加载文件的语法规则:

  (加载取名称)      (基地址)   (属性)  (大小)

  {

    (执行区名称)   (基地址)   (属性)    (大小)

    {

      ;放置某种属性的代码

      ;放置某种属性的代码

      ;。。。。。。

    }

  。。。。。。

  }

。。。。。。

其中(属性)是可选的,加载区的基地址跟第一个执行区的基地址必须是相同的。

2、抛砖引玉,DA14580的程序空间划分

LR_IROM5 (0x20000440) (0x8BE0)                       ;定义了名称为LR_IROM5的加载域,起始地址为0x20000440,大小为0x8BE0,接近35KB
{ ;
ER_IROM5 (0x20000440) (0x8BC0) ;定义了名称为ER_IROM5的执行域,此域为LR_IROM5的第一个执行域,起始地址跟
{ ;LR_IROM5的起始地址一样,大小为0x8BC0
*(InRoot$$Sections) ;*为通配符,放置位于根区的所有库的部分如__main.o、__scatter*.o等
boot_vectors.o (+RO) ;放置boot_vectors.o中的RO属性代码
system_ARMCM0.o (+RO) ;
.ANY (+RO) ;放置所有的RO属性的代码
} ;
RW_IRAM52 (0x20009000) EMPTY 0x20 {} ;RMPTY为属性字段,这里表示空0x20这么多空间
} LR_IROM7 (0x20009020) (0x17E0) ;
{ ;
ER_IROM7 (0x20009020)(0x11E0-NON_RET_HEAP_SIZE) ;
{ ;
.ANY(+RW) ;放置所有的RW属性的代码
} ;
RW_IRAM72 (0x2000A200 - NON_RET_HEAP_SIZE) UNINIT NON_RET_HEAP_SIZE ;
{ ;
jump_table.o (heap_mem_area_not_ret) ;放置jump_table.o中的heap_mem_area_not_ret属性的代码
} ;
RW_IRAM73 (0x2000A200) UNINIT 0x600 ;未初始化的0x600空间
{ ;
.ANY (STACK) ;作为栈使用
}
}

3、追根溯源,遇到的问题以及原因分析

  先贴张编译失败的图片:

  

  no space in execution regions with .ANY selector matching   ****

  还有那种  ****(执行域名称) 缺少多少字节的编译错误

  以上都是某个执行域分配的空间不够的问题,解决的关键是,先找到是哪个执行域空间不够,再想办法扩大,或者把这个执行域内的某个属性的代码放到其他执行域内。

  

  这个是程序编译没问题,但是调试运行,根本进不了main(),就进入硬件中断了。其堆栈信息如上图。说明是初始化变量时,空间不够,解决办法一样,扩大那个执行域,或把那个执行域内一个或几个属性的代码放到其他执行域内。

4、码随心动,自由安排代码位置

  根据以上学习,是否学会了自己编写分散加载文件了呢?

最新文章

  1. poj1007-DNA Sorting(排序)
  2. 学习UFT11.5历程(二)
  3. css 设置背景图片模糊,内容不模糊
  4. Android 的系统架构
  5. 无法连接windows虚拟机oracle的解决办法
  6. mybatis使用小记
  7. 使用架构(XSD)验证XML文件
  8. android之AutoCompleteTextView控件用法
  9. iso中第三方框架SDWebImage的使用步骤
  10. Android onActivityResult 设置requestCode 返回的code不对
  11. PHP内置函数getimagesize()的漏洞
  12. javascript关键字加亮加连接
  13. CAD教程/视频教程/软件类专题资料免费下载整理合集
  14. C语言sqrt函数
  15. Eclipse rap 富客户端开发总结(13) :Rap/Rcp保存按钮处理方式
  16. NLog组件
  17. 数据库【mongodb篇】基本命令学习笔记
  18. 使用Spring的@Async创建异步方法
  19. 刷题upupup【Java中HashMap、HashSet用法总结】
  20. 网页真机调试之Browsersync简介

热门文章

  1. 将pugixml库编译成动态库的做法
  2. Azure 5 月新公布
  3. Office加载项安装
  4. 笨办法学Python(二十七)
  5. 257. Binary Tree Paths (dfs recurive & stack)
  6. ZOJ - 2112 Dynamic Rankings(BIT套主席树)
  7. POJ-3009 Curling 2.0---DFS求最短路
  8. 问题 C: B C++时间类的运算符重载
  9. 2017.11.18 C语言的算法分析题目
  10. windows 平台使用 VS2017 编译 libevent 源码