首页 > 解决方案 > 强制编译器/链接器按照定义对变量进行分组(物理上位于连续 RAM 位置)

问题描述

如何强制编译器(使用我假设的选项开关)将变量按定义的顺序在物理的、连续的 RAM 位置中组合在一起?我真的不在乎它从哪里开始(也就是说 - 它放在哪里MinWaitTime。但是,FaultCode必须立即位于MinWaitTimeRAM 之后。它不能把它放在其他地方。

我想过创建一个部分,但这只能保证它们放在一起,而不一定按照它们定义的顺序。

我知道我可以创建和排列来强制解决这个问题,但我想避免它。

有什么建议么 ?

例如,如果MinWaitTime在地址 0x20000000 处,我想FaultCode在 0x20000002 处定义,并按该顺序定义所有其他变量。

unsigned short  MinWaitTime;        // reg 450

unsigned short  FaultCode;          // reg 451

unsigned short  FaultReg1;          // reg 452

unsigned short  FaultReg2;          // reg 453

unsigned short  Reserved2;          // reg 454

unsigned short  Reserved3;          // reg 455

unsigned short  SystemStatusReg1;   // reg 456

unsigned short  SystemStatusReg2;   // reg 457

编译器是 GCC。

标签: cgcc

解决方案


有几种方法可以解决这个问题。

结构+宏

最简单的方法就是使用结构体,可能带有宏:

struct {
    unsigned short MinWaitTime;
    unsigned short FaultCode;
    ...
} vars;

#define MinWaitTime (vars.MinWaitTime)
#define FaultCode (vars.FaultCode)
...

这很好,因为这正是结构的设计目的,但宏并不好。

理论上,“全局匿名结构”可以做到这一点,因此您可以在没有宏的情况下执行此操作,但这不存在。

意见:我会使用结构,但没有宏。

部件

你可以做到这一点的另一种方法是在组装的帮助下。您可以使用以下代码创建单独的程序集源文件:

    .data
    .align 2

    .globl MinWaitTime
MinWaitTime:
    .zero 2

    .globl FaultCode
FaultCode:
    .zero 2

    .globl FaultReg1
FaultReg1:
    .zero 2

    .globl FaultReg2
FaultReg2:
    .zero 2

这定义了连续地址的变量。然后,您可以从 C 中访问它们,只需在 C 源代码中的某处声明它们即可:

extern unsigned short MinWaitTime;
extern unsigned short FaultCode;
extern unsigned short FaultReg1;
extern unsigned short FaultReg2;

extern是唯一必要的,这样您就不会得到重复的定义。

然后,编译并将 C 和汇编文件链接在一起。

笔记

请注意,我们在这里明确不关心可移植性。


推荐阅读