软件Overlay:程序编写与调试

Facebook
Twitter
LinkedIn

赖歆雅,技术经理,晶心科技股份有限公司

  近几年来,SOC 为了支持更大的硬件资源,及更精确的算法,很多应用中的软件程序代码越来越大,但是售价却要越来越便宜。各家厂商无不绞尽脑汁寻找降低成本的方法。
  SRAM 在 SOC 上,是一个快速但单位面积较大的组件,而单位面积较大代表成本较高。有一个降低成本的方法,是将程序代码放在较慢但单位面积较小的 flash 或 ROM 上,当系统需要执行里面的某些程序代码时,才加载到内存里执行。
  如果用商店来比喻的话,有一个小店租在都市里的黄金店面里,小店的展示柜很小,当客人想要看架上没有的商品时,店员才从后面较大的仓库里,把商品拿出来放到展示柜上。这里的展示柜就像 SRAM,昂贵但是有效率,仓库就像 flash,便宜容积大但是存取较麻烦。
  本文介绍的是软件 overlay 的技术。除此之外,晶心科技也发展了硬件overlay 的技术,使得 overlay 执行更快,操作更为简单。期望本文章能对使用者有所帮助,也希望读者不吝指教提供您宝贵的意见。

1. 软件 Overlay 技术介绍及操作
  我们举一个实际例子作为说明,比方说程序代码的大小为 210KB,RAM 只有 64KB,我们把 RAM 规划成一格一格的大小,比方说每 4KB 切成一块。每4KB 的大小可以在不同时间,更换成不同的程序代码,可以重复利用 RAM 的空间。程序代码储存在 ROM 或flash 里,只有在执行之前会将函数从 ROM 或flash 里动态加载 SRAM 里。当这个函数执行完成,下一个函数要执行前,再加载下一个函数。
  值得注意的是,每一格 SRAM 里可加载的程序代码是互斥的,比方说有些不会同时使用的功能可以放在同一格里,比方说 mp3 播放器,录音和播放不会同时使用,就可以规划重复利用同一格 SRAM。

1.1 系统架构
  请参考图表 1,右边长方形是 flash 的内容。0x0 起 1MB 的空间,flash 里存放了程序代码和.data,及各个即将要被 overlay 的 sections。
  图表1的左边长方形是SRAM规划,地址从0x10000000开始,我们切出三格提供overlay的SRAM,分别是0x10800000, 0x10804000及0x10808000。Overlay要规划成几格,或者每一格要切成多大块,都是由使用者规划。这里的SRAM与flash的地址是以通用型Andes FPGA开发板作例子。读者设计SOC时,可以根据实际需求定义合理的地址。
  程序执行时,0x10800000可以加载.ovly0或是.ovly1。0x10804000可以加载.ovly3或是.ovly2。0x10808000可以加载.ovly4或是.ovly5。

图表1. 系统架构图

1.2 overlay 的 sag 文件编写
  图表 2 是范例 sag 文件。Sag 文件是 Andes linker script generator 所需要的输入文件,执行linker script generator 后,输出会产生GNU linker 需要的linker script。详细语法说明可以参考 Andes BSP v3.2.0 User manual 第 12 章。
  我们简单介绍图表 2 的语法。第 1 行关键词 USER_SECTIONS 表示后面接的这几个 sections 都是由使用者自定义的 sections。在后面的章节,笔者会介绍如何把函数指定为这些自定义 sections。

图表2. sw-ovly.sag文件

  图表2中,第4行表示从0x0开始的区域是只读区,包含程序代码(.text section) 及只读数据段(.rodata section)。第9行,OVLY0从0x10800000开始,里面有2 个sections可overlay,一个是.overlay0,另一个是.overlay1。以此类推,在OVLY1 和OVLY2都各有2个sections可以overlay。第24行的RAM1里放的是.data及.bss sections,执行时期会从0x10000000开始。

1.3 sag 文件转成 linker script
   如图表3,在cygwin下执行nds_ldsag软件,将sw-ovly.sag转成sw-nds32.ld 文件。参数-o sw-nds32.ld为指定输出文件名。nds_ldsag软件可以在AndeSight 2.0.1 MCU或是BSP v3.2.0里取得。

图表3. Sag文件转换

1.4 程序里指定函数或变量放在自定义的 sections
  GNU ld (linker)可连结目标文件为可执行文件,排列上的最小单位是section, 基本的sections为.text,.data及.bss这3个sections。为了达成分区overlay的功能,必须指定函数或是变量在自定义的sections上。在前一节里我们介绍了我们切出 3个区域可以做overlay,分别是OVLY0(从0x10800000起),OVLY1(从0x10804000起)及OVLY2(从0x10808000起)三个区域。指定函数overlay0放在自 定义section .overlay0里,要使用 __attribute__ ((section(“.overlay0”)))语法, 完整写法请参考图表4a。图表4b.是另外一种写法。

指定全局变量gdata1放在自定义section .overlay4里,要使用 attribute ((section(“.overlay4”)))语法,完整写法请参考图表5。

图表5. 指定变量放在自定义section

1.5 各 sections 的 LMA 与 VMA
  图表6,是各个section的LMA和VMA。在这个表上,可以看.andes32_init 到.sdata_w的LMA从0x0~0x29dc,这些section的LMA是连续的。.overlay0 与.overlay1做overlay,所以有共同的VMA 0x10800000。同样的,.overlay2 和.overlay3,具有共同的VMA 0x10804000。.Overlay4和.overlay5,也有同样的VMA 0x18008000。

图表6. 各sections的LMA和VMA

1.6 overlay 程序的加载
  前面已经介绍overlay section的sag文件写法。那么如何加载用户想要用的overlay程序呢?
  请看图表7,这是overlay的执行程序代码。第5行OverlayLoad(0)表示載入section .overlay0。第6行OverlayLoad(4)表示载入section .overlay4。第7行在.overlay0被加载后,执行overlay0(),可以正常工作。

图表7. Overlay sections的使用方法

  再来我们介绍一下Overlay manager的程序运作,Overlay manager即为图表7中的函数OverlayLoad。图表8列出Overlay manager代码段,主要做了两件事。一,修改mapped table _ovly_table,标示overlay section是mapped或是unmapped。_ovly_table的用途是让gdb知道目前加载的是哪一个section,使得gdb在debug时,能自动切换为正确的调试信息。
  二,在程序执行时期将函数加载,函数ovly_copy是一个memcpy函数,将函数从LMA复制到VMA上。当OverlayLoad(0)执行完后,overlay0函数主体便存在于VMA上,可正确的执行。

图表8. Overlay manager代码段

  图表9为_ovly_table的内容,要标示每一个overlay section的vma, size, lma, 和是否mapped。必须要注意的一点,_ovly_table要位在一个lma等于vma的区域里。

图表9. _ovly_table的内容

2. 调试 Overlay 的程序
  开启自动overlay调试功能的gdb命令是overlay auto。当overlay auto开启后, 对于使用者来说,与一般程序的调试方法相同。
  图表8的最后一行_ovly_debug_event()的用途是让gdb能把断点加在正确的地址上,这一行要写在OverlayLoad的后面。必须要有这一行,gdb的自动overlay调试才能正常。
  当用户加一个断点在被overlay的区域,gdb会在函数被加载之后(即为执行完OverlayLoad),遇到_ovly_debug_event时,自动的把断点加到overlay的地址上。

3. 参考数据
  Overlay Commands
https://sourceware.org/gdb/onlinedocs/gdb/Overlay-Commands.html

Automatic Overlay Debugging https://sourceware.org/gdb/onlinedocs/gdb/Automatic-Overlay-Debugging.html#Auto matic-Overlay-Debugging

Debugging Programs That Use Overlays http://davis.lbl.gov/Manuals/GDB/gdb_11.html

Andes BSP v3.2.0 User Manual
Chapter 12 “Linker Script Generation”

4. 结语
  善用 overlay 技术可以更有效率地使用快速但昂贵的 SRAM,在执行时,容纳比 SRAM 实际大小更大的程序,设计出高效率小面积的 IC。