新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Andes SAG应用实例

Andes SAG应用实例

作者:时间:2014-12-04来源:电子产品世界收藏

  在开发中,系统软件设计特别是各种的规划是必不可少的一个环节,它也直接体现在链接脚本的撰写上。 因链接脚本的语法相对复杂和篇幅较大,前期撰写和后期维护对工程师来讲难度都很大, 但对使用AndesCore做开发的工程师来讲,Andes SAG是一大福音,它提供简单直观的描述语言替代了复杂的链接脚本。我们收到的反馈也证明,越来越多的工程师开始采用Andes SAG替代linker,之前我们有一篇技术文章对SAG的语法格式做了介绍并说明如何使用,本文将展示四个实际工程开发的例子,以帮助广大开发者更好的熟悉和理解Andes SAG,同时可以作为开发时的参考。

本文引用地址:http://www.eepw.com.cn/article/266369.htm

  1.将函数和变量指定到特定地址

  第一个例子是如何将函数和变量的地址指定到一个特定的地址,例子中的地址指运行地址——VMA。有这样要求的原因有很多,诸如SOC的运行地址空间不连续,或者需要高效使用某一块效率很高的等情况。解法分为两步:一,在SAG文件中添加自定义的section,将此section的VMA设定到指定地址;二,在C语言中,将需要改变的函数和变量用特定的语法放在自定义的section。

  图表1是在SAG中自定义section 的例子。第1行关键词USER_SECTIONS表示后面接的这几个sections都是由使用者自定义的sections。

    

 

    

 

  图表1. Samp1.sag文件

  图表1中,第4行至8行表示从0x0开始的区域是只读区,包含程序代码(.text section)及只读数据段(.rodata section)。第9行,MYRAM0部分表示.mysection0的VMA从0x00014000开始。以此类推,MYRAM1和MYRAM2部分各自表示mysection1和.mysection2的VMA起始位置。第21行的RAM1里放的是.data及.bss sections,执行时期会从0x00010000开始,源代码中须做到将data 的LMA地址copy至 VMA位置,可以使用 __data_lmastart 与 __data_start 来寻址。

  指定函数放在自定义section里,在源代码的对应处要使用__attribute__((section(".mysection0")))语法,完整写法请参考图表2a。图表2b是另外一种写法。

    

 

  图表2a. 指定函数放在自定义section

    

 

  图表2b. 指定函数放在自定义section的另一种写法

  指定全局变量gdata1放在自定义section .mysection1里,在源代码的对应处要使用__attribute__((section(".mysection1")))语法,完整语法请参考图表3。

    

 

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

  将函数和变量这样指定后,编译后的adx(elf)文档可以清晰看到对应Section的LMA与VMA如图表4.

    

 

  图表4. ELF Header

  2.实现IVB在运行时切换

  有一个客户需要系统在开机与正常运行时能有不同的ISR,即是同一个中断的服务函数在开机和正常运行时会不一样。对于这个问题的解法有很多,我们今天介绍是其中一种解决方法:设置一个新的Vector Table,新的Vector Table会跳到新的ISR;通过SAG将新的Vector Table指定到一个特定地址上;当程序开机完成,需要正常运行时,只需要去修改IVBASE (ir3)这个寄存器。

  所以完成这个例子的重点是如何在汇编代码中建一个新的vector table 并指定到自定义的section中。表5是实例的写法:

    

 

    

 

  图表5 指定Vector table到自定义section

  图表5重点是是第一行,.section 是用来定义非标准的section,.nds32_aa 即为非标准section的名称,”a”表示allocable, “x”表示executable. 因为Andes的标准vector table一般会放在.nds32_init section,所以新的vector table 放.nds32_aa里,名称不一样能区别就好。接下来是让新的自定义section .nds32_aa 运行在特定地址上,如图表6所示。

    

 

    

 

  图表6 指定自定义section到特定地址

  这样新的vector table的首地址会被固定到0x10000的位置,当程序开机完成,只需要将IVBASE设定到这个地址,那么当有中断进来,就会跳到新的Vector Table中。

  3.指定一个或几个C档的所有section到指定地址

  上两个例子有共同点是通过编程将某一段程序放到自定义section,区别在于一个是指定C语言函数和变量到自定义section,一个指定汇编函数到指定的section,都需要改动源代码。然而对于一些应用场景,比如不提供源代码只有编译好的.o或者.a 文件,如果想将.o档里的section指定到特定地址运行,这个时候该如何做呢?请参考图表7A的写法,这表示我们要将hello.o的只读区,包含程序代码(.text section)及只读数据段(.rodata section)放在LMA及VMA在0x10000的地址上。

    

 

  图表7A 指定自定义section到特定地址

  在整个project 中如果将每个.o档都列出来,那么整个SAG文档将变得难以阅读,而且在给后期维护带来麻烦,这种解法不好。如果使用者只需要排除几个.o檔,对于熟悉GNU linker的读者会想到“EXCLUDE_FILE”这一语法,让使用者可以很方便地在Linker中实现这一需求。Andes SAG也与时俱进地引入这一语法。图表7B正是这样一个例子,它将uart.o中所有的section 都放到一个特定地址去运行,而其它的保持不变。

    

 

  图表7B 支持“EXCULDE_FILE”

  4、如何避免LMA或VMA的偏差

  在前三个例子中,都是举例去说明如何实现将程序的某一部分的LMA或者VMA固定在某一个特定地址上,这是对链接这一动作的基本要求。软件工程师需要知道,当某一section的LMA与VMA不相等时,那么在程序初始化时需要将这一section从LMA的地址拷贝到VMA的地址。初始化做拷贝时,这些section的LMA和VMA都是在链接脚本中赋值的,代码中只是去做引用。

  Andes SAG同样可以给变量赋值LMA和VMA,但如何赋值呢,是不是一个一个紧凑地排列下来?答案很显然是不。很多工程师都知道,数据存放有Alignment的要求,比如4 Byte 的Word其存放的首地址需要是4 Byte Align;程序呢,因为优化的需要,比如在Andes 编译器在-Os等级下,函数的首地址同样强制4 Byte Align。既然有对齐的要求,就必然有gap存在,当然这里举出的对齐因素只是让读者了解到链接器对某一section的LMA或VMA的数值确定不只是单纯累加,Andes SAG能自动处理好大部分对齐状况。但在一些较复杂的例子中,需要给Andes SAG更多指示,让它工作正确。

  首先,我们来看图表7所举出的例子,这一行“LOADADDR NEXT __uart_lmastart”,有一个关键字“NEXT”。它的作用就是让SAG知道,这个变量的取值是下一个Section的开始,而不是上一个Section的结束。为了让读者更明白所表示的含义,我们首先来看依照图表7的SAG编译出的elf(adx)档header信息,如图表8:

    

 

  图表8 adx header

  可以看到.text_*uart.o 的LMA应该是0x1c60, 上一个section(.bss)的LMA结束地址应为:0x1c48+0x10=0x1c58,所以为了清晰地让SAG知道__uart_lmastart代表.text_*uart.o的LMA开始而不是.bss的LMA结束,我们应该用NEXT去修饰它。

  然后,我们再来看图表9的例子,这个例子中,使用“LMA_FORCE_ALIGN”的原因是因为可能某一个section的size 只有2 Byte(不是4 Byte的整数倍),但下一个section的VMA 起始地址需要4 Byte Align,这时就会出现冲突,为解决冲突,Andes SAG引入这一关键字“LMA_FORCE_ALIGN”,强制让LMA与VMA用同一个值去做Align。

    

 

  图表9 “LMA_FORCE_ALIGN”example

  我们用图表9的SAG 例子去编译对应的project,可以看到图表10中section .sbss_b的LMA已经被从0x1d42调整到0x1d44。

    

 

  图表10 “LMA_FORCE_ALIGN”的效果

  5、结语

  Andes提供通俗易用的SAG工具帮助工程师替代了复杂的链接脚本,可以大大提高在Andes core平台上的软件开发效率。本文从实际例子出发,介绍了Andes SAG 工具如何快速解决工程实际问题,说明了Andes SAG强大而且容易上手。然而工具的功能越强大,也就需要工程师多加深入了解功能设计的缘由,这也正是最后一个例子展现出来的道理,即是透彻了解就可以熟能生巧。希望广大读者能熟练掌握Andes SAG这样一把利器,在软件开发中发挥四两拨千斤的作用。

  参考文档:

  1: BSP321 programming guide link generator

  2: The GNU Linker Manual

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

可控硅相关文章:可控硅工作原理


c语言相关文章:c语言教程


比较器相关文章:比较器工作原理


存储器相关文章:存储器原理




评论


相关推荐

技术专区

关闭