基于Tricore的Tasking链接文件解读

目录

1.链接文件有什么用?

2.文件结构和语法解析

2.1 文件结构

2.2 语法解析

3.小结


玩惯了ld文件,突然让搞lsl,被其中花里胡哨的语法搞晕了,例如:

    memory cpu0_dlmu
    {
        mau = 8;
        size = 64k;
        type = ram;
        map     cached (dest=bus:sri, dest_offset=0x90000000,      size=64k);
        map not_cached (dest=bus:sri, dest_offset=0xb0000000, size=64k,priority=8);
    }

虽然这个字面意思写的很清楚,但是在链接器实际运行时有什么不一样吗,mau、priority具体表示什么?因此有必要搞一搞其底层原理。

编译原理这里就不多谈了,咱们直接从链接器开始走起。

1.链接文件有什么用?

Tasking 链接器将Linker和Locator集合到一起, Linker阶段主要把 .o文件、lib文件组合成一个可重定位的对象文件,例如.out;Locator主要用于给上述.out文件重新分配绝对地址,并生成目标处理器的文件,例如elf、hex、s19等,总体流程如下图:

在连接过程中,lsl(Linker Script Language)文件起到了非常关键的作用:

  • 确定当前目标处理的内核硬件架构,例如逻辑地址和物理地址的偏移等;
  • 确定当前系统的memory位置,例如RAM、ROM首地址和长度等;
  • 确定代码数据放到memory的什么位置,这也是我们主要关心的点,控制数据代码到指定位置;

有了上述基本了解,我们来看看lsl的一些关键语法。

2.文件结构和语法解析

2.1 文件结构

lsl链接文件主要包含如下几个部分:

  • 内核架构的定义:帮助linker将目标内核的逻辑地址转换为物理地址,可能还包括中断向量表、栈的定义等,一般来说编译器会把这个定义好,例如tc1v1_6_2.lsl;
  • 派生的定义:主要是用于描述内部总线定义、memeory定义等;
  • 处理器的定义:用于定义单核还是多核,以及对应内核实例
  • 段的定义:控制自定义段的具体位置

 框架如下如下:

2.2 语法解析

首先来看几个最常见到但是没有关心过的关键字,以开头代码为例:

  • mau:Minimal Addressable Units,最小可寻址单元,对Tricore来说就是1 byte,对应数字 8;
  • type:指定memory类型,常见的如rom,ram,nvram(任意时刻都可以修改),blockram
  • map:该关键字将源地址转为目的地址,具体映射关系如下:
  • space => space
  • space => bus
  • bus => bus
  • memory => bus

上述几个关键字接下来我们就来分析几个常用的语法。

定义memory的基本格式如下:

memory mem_name
{
    type = xx;
    mau = xx;
    size = 64k;
    map map_name ( map_description );
}

以定义TC3xx CPU0 DSPR的空间为例,代码如下:

    memory dsram0 // Data Scratch Pad Ram
    {
        mau = 8;
        size = 240k;
        type = ram;
        map (dest=bus:tc0:fpi_bus, dest_offset=0xd0000000, size=240k, priority=8);
        map (dest=bus:sri, dest_offset=0x70000000, size=240k);
    }

mau = 8,表示最小寻址单位为1 byte;整块memory为240k,属于ram类型;比较好玩的是下面两块map,我们来看第一个:

map (dest=bus:tc0:fpi_bus, dest_offset=0xd0000000, size=240k, priority=8);

目的地是Tricore 0 的FPI 总线,偏移为0xd0000000,size为240k,优先级为8;我们回过头看TC3xx的手册,会发现CH、DH这个Segment是保留的,这就奇怪了,链接文件为什么要定义这个东西?直觉告诉我这个可能和Tricore寻址方式有关系。

 fpi_bus用于将CPU\DMU等高速外设连接至中低带宽外设,对应具体实例为SPB(系统外设额总线)、BBB(ADAS domain相关),位宽32bit;如下图:

其次,针对CH\DH的用途在map中也给出体现,如下 

 

 我们继续翻看5.3.6.1.1章节,详细描述了本地和全局寻址方式。

核内DSPR位置始终为0xD0000000,PSPR为0xC000000,可以理解这是本地地址;而在多核系统中,根据Core ID,PSPR和DSPR分别对应1-7H,这就是所谓的全局地址如下:

但是,还有但是,CPU始终是用全局进行总线传输,意味着即使CPU0从本地DSPR拿数据,仍然使用是的7000000的地址。

所以紧接着定义了关于多核globle的map,如下:

map (dest=bus:sri, dest_offset=0x70000000, size=240k);

那么在链接的时候,linker如何知道用0x7开头还是0xd开头的呢?根据后面的priority优先级来定。

在测试优先级的时候,上面关于DSPR的例子举的不好,因为不管我怎么调优先级都还是用的global地址,除了在调试时将某些指定到本地地址,如下:

 所以换个DLMU来搞,cpu0_dlmu memory定义如下:

memory cpu0_dlmu
{
    mau = 8;
    size = 64k;
    type = ram;
    map     cached (dest=bus:sri, dest_offset=0x90000000, size=64k);
    map not_cached (dest=bus:sri, dest_offset=0xb0000000, size=64k);
}

我们将变量放到cpu0dlmu0,在不设置优先级的情况下,编译结果如下:

将not_cached地址优先级提高,结果如下:

这里我们基本可以得出结论:数值越高,优先级越高。

我们将cached\not_cached的代码互换位置,优先级不变,结果如下:

这就很神奇了,好像不是优先级相同,先到先得,而是默认为cached,这是为什么呢?

我们就从这个变量放置的段来找答案,对于section的定义,有两种关键词:

section_setup:定义堆栈、copy、table、启动地址等等

section_setup ::my_space
{
    reserved address range
    stack definition
    heap definition
    copy table definition
    start address
    space reference restrictions
    input section modifications
    section reference restrictions
    MPU data table
}

section_layout:定义一个或者多个section,并赋予section一个地址空间,可以指定运行地址、加载地址,section空间大小等等;可以这样理解,我们写的代码、数据存放位置是在linker里lsl里的section指定,在车规中常常会会将标定数据、信息安全数据等放置到特定位置,因此掌握这部分内容是比较重要的。

实例如下:

仔细看,在示例中section_layout里还定义group了,它包含了一个或者多个input section,因此需要使用语法select 选择section。

在上一个试验中,我们把g_DataTest放到了section lmubss_cpu0,如下图:

该section在lsl链接文件中定义如下:

注意看,此时run_addr为cpu0_dlmu,对应memory:

编译出来是cached地址,那有没有办法让它在non-cached的地址? 

根据lsl说明,使用语法:

group (run_addr = mem:A/map_name)

 修改如下:

编译得到结果如下:

3.小结

上面两节将lsl的基本框架和常用语法进行了梳理,其中比较重要的就是memory定义和section定义,这里最后再总结下如何将数据或者代码放到指定位置:

  1. 首先定义一块memory,使用语法memory name{ },指定map地址,mau,size;
  2. 在section_layout里用group定义运行地址,如有必要定义加载地址;
  3. 代码里在待处理的数据或者代码前后添加限定符#pragma,或者__attribute__ ((section  ".name"))

  • 22
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CyberSecurity_zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值